home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / smaltalk / st80_pr4.lha / st80_pre4 / Foible / FlowKit / FlowKit2.st < prev    next >
Text File  |  1993-07-24  |  91KB  |  4,117 lines

  1. 'From Tektronix Smalltalk-80 version T2.2.0cM3, of September 21, 1987 on 18 May 1990 at 7:18:26 pm'!
  2.  
  3. BoxWithPorts subclass: #FlowKitBox
  4.     instanceVariableNames: 'permanentForm value companion '
  5.     classVariableNames: 'SmallTextStyle '
  6.     poolDictionaries: ''
  7.     category: 'FlowKit'!
  8. FlowKitBox comment:
  9. 'FlowKitBox is the abstract class for all Boxes in FlowKit
  10.  
  11. instance variables:
  12.  
  13. permanentForm is the form that holds the FlowKitBox''s basic image
  14.  
  15. value holds the value of the FlowKitBox
  16.  
  17. companion is the Box that corresponds to the FlowKitBox in
  18. the other view'!
  19.  
  20.  
  21. !FlowKitBox methodsFor: 'calculations'!
  22.  
  23. calculateValue: someValues 
  24.     "calculate the receiver's value given the input someValues"
  25.  
  26.     | formulas |
  27.     formulas _ self formulas.
  28.     someValues isEmpty
  29.         ifTrue: [self value: (formulas collect: [:each | each value: self])]
  30.         ifFalse: [self value: (formulas collect: [:each | each valueWithArguments: someValues asArray])].
  31.     ^self value!
  32.  
  33. firstValue
  34.     "return the first value of the receiver"
  35.  
  36.     ^self value at: 1!
  37.  
  38. firstValue: aValue 
  39.     "set the first value of the receiver"
  40.  
  41.     self value at: 1 put: aValue!
  42.  
  43. getInputValues
  44.     "get the input values needed for a calculation of the 
  45.     receiver's value"
  46.  
  47.     inputPorts do: [:each | each value isNil ifTrue: [^nil]].
  48.     ^inputPorts collect: [:each | each value]!
  49.  
  50. initValue: aValue 
  51.     "give the receiver an initial value"
  52.  
  53.     self value: aValue!
  54.  
  55. outputResults: results 
  56.     "display the results of the receiver's calculation"
  57.  
  58.     self displayValue: results.
  59.     outputPort with: results do: [:prt :res | prt token: res]!
  60.  
  61. token
  62.     "the sender, an input port, has received a new value for  
  63.     use in the         
  64.     receiver's calculation" 
  65.  
  66.     | values results |
  67.     values _ self getInputValues.
  68.     values isNil ifTrue: [^nil].
  69.     results _ self calculateValue: values.
  70.     self outputResults: results!
  71.  
  72. value
  73.     "return the value of the receiver"
  74.  
  75.     ^value!
  76.  
  77. value: aValue
  78.     "set the value of the receiver"
  79.  
  80.     value _ aValue! !
  81.  
  82.  
  83. !FlowKitBox methodsFor: 'interface tests'!
  84.  
  85. acceptsDataLinks: aPoint 
  86.     "Return whether I accept DataLinks  
  87.      at the user interface"
  88.  
  89.     | port | 
  90.     port _ self findInputPort: aPoint.
  91.     ^port isNil not!
  92.  
  93. canAcceptInput
  94.     "by default, boxes can't accept input"
  95.  
  96.     ^false!
  97.  
  98. canBeCalibrated
  99.     "Return whether I can be calibrated"
  100.  
  101.     ^false!
  102.  
  103. givesDataLinks: aPoint 
  104.     "Return whether I give DataLinks   
  105.      at the user interface"
  106.  
  107.     | port |
  108.     port _ self findOutputPort: aPoint.
  109.     ^port isNil not! !
  110.  
  111.  
  112. !FlowKitBox methodsFor: 'displaying'!
  113.  
  114. displayBox
  115.     "returns boundingBox of the receiver if it displays its  
  116.     value, nil otherwise"
  117.  
  118.     ^nil!
  119.  
  120. displayValue 
  121.     "displays the receiver's current value"
  122.  
  123.     ^self subclassResponsibility!
  124.  
  125. displayValue: someValues 
  126.     "display someValues, the receiver's new value,  
  127.           implemented by subclass"
  128.  
  129.     ^self! !
  130.  
  131.  
  132. !FlowKitBox methodsFor: 'form access'!
  133.  
  134. addInput: aValue toForm: aForm 
  135.     "display aValue on aForm and return it"
  136.  
  137.     self subclassResponsibility!
  138.  
  139. baseForm
  140.     "Return a copy of the Form representing the receiver"  
  141.  
  142.     ^permanentForm deepCopy!
  143.  
  144. createForms
  145.     "This is the method that creates the form."
  146.  
  147.     | aForm |
  148.     aForm _ self baseForm.
  149.     aForm offset: 0@0.
  150.     forms add: aForm!
  151.  
  152. inputForm
  153.     "return a copy of the receiver's form with the current input 
  154.     displayed "
  155.  
  156.     self subclassResponsibility!
  157.  
  158. inputForm: aValue
  159.     "return a copy of the receiver's form with aValue 
  160.     displayed on it"
  161.  
  162.     self subclassResponsibility!
  163.  
  164. permanentForm: aForm
  165.     "set the permanent form of the receiver to be aForm"  
  166.  
  167.     permanentForm _ aForm! !
  168.  
  169.  
  170. !FlowKitBox methodsFor: 'initialization'!
  171.  
  172. initializeAt: aPoint withName: aName withForm: aForm superManager: aManager
  173.     "initialize the new FoibleBox at aPoint with form aForm  "
  174.  
  175.     name isNil ifFalse: [^self error: 'Cannot reinitialize a ' , self class name].
  176.     name _ aName.
  177.     self permanentForm: aForm.
  178.     self offset: aPoint.
  179.     owner _ aManager! !
  180.  
  181.  
  182. !FlowKitBox methodsFor: 'accessing'!
  183.  
  184. acceptInput: aPoint 
  185.     "default method for a box to get input, if it accepts input. 
  186.     The point where the box was poked is supplied if needed."
  187.  
  188.     | oldInput newInput |
  189.     oldInput _ self value.
  190.     oldInput isNil
  191.         ifTrue: [oldInput _ '']
  192.         ifFalse: [oldInput _ oldInput first].
  193.     newInput _ FillInTheBlank request: 'Enter Input for this Box' initialAnswer: oldInput printString.
  194.     ^newInput!
  195.  
  196. companion
  197.     "return the box which is the receiver's companion box"
  198.  
  199.     ^companion!
  200.  
  201. companion: aBox
  202.     "let the receiver know that aBox is its companion box"
  203.  
  204.     companion _ aBox!
  205.  
  206. formulas
  207.     ^self class formulas! !
  208.  
  209.  
  210. !FlowKitBox methodsFor: 'port access'!
  211.  
  212. findInputPort: aPoint 
  213.     "find and return an input port that can be linked to at aPoint"
  214.  
  215.     inputPorts isNil ifTrue: [^nil].
  216.  
  217.     "see if user hit a port right on the nose. If so give it to him."
  218.     inputPorts do: [:each | ((each boundingBox containsPoint: aPoint)
  219.             and: [each link isNil])
  220.             ifTrue: [^each]].
  221.  
  222.     "If no input port was hit, return first empty one."
  223.     inputPorts do: [:each | each link isNil ifTrue: [^each]].
  224.  
  225.     "If none available ..."
  226.     ^nil!
  227.  
  228. findOutputPort: aPoint 
  229.     "find and return an output port that can be linked to at 
  230.     aPoint "
  231.  
  232.     outputPort isNil ifTrue: [^nil].
  233.     outputPort  do: [:each | ((each boundingBox containsPoint: aPoint)
  234.             "and: [each link isNil]" ) " ask Dan if this is correct "
  235.             ifTrue: [^each]].
  236.     ^nil!
  237.  
  238. initInputPortsFromRectangles: rectangles 
  239.     "initialize the input ports of the receiver"
  240.  
  241.     inputPorts _ rectangles collect: [:each | (FlowKitInputPort new: each)
  242.                     box: self]!
  243.  
  244. initOutputPortsFromRectangles: rectangles 
  245.     "initialize the output ports of the receiver"
  246.  
  247.     outputPort _ rectangles collect: [:each | (FlowKitOutputPort new: each)
  248.                     box: self]! !
  249.  
  250. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  251.  
  252. FlowKitBox class
  253.     instanceVariableNames: 'formulas '!
  254. FlowKitBox class comment:
  255. 'The class instance variable formulas holds a collection of
  256. blocks that are evaluated when the FlowKitBox''s value is
  257. calculated,  each formula''s value is sent to a corresponding
  258. output Port'!
  259.  
  260.  
  261. !FlowKitBox class methodsFor: 'accessing'!
  262.  
  263. formulas
  264.     ^formulas! !
  265.  
  266.  
  267. !FlowKitBox class methodsFor: 'displaying'!
  268.  
  269. asCursor
  270.     "return an image of the receiver which can be used as a cursor"
  271.  
  272.     ^self baseForm deepCopy! !
  273.  
  274.  
  275. !FlowKitBox class methodsFor: 'instance creation'!
  276.  
  277. offset: aPoint withName: aString withForm: aForm
  278.     "create aType FoibleBox at aPoint with form aForm"
  279.  
  280.     | foibleBox |
  281.     foibleBox _ super new.
  282.     foibleBox initializeAt: aPoint withName: aString withForm: aForm.
  283.     ^foibleBox!
  284.  
  285. offset: aPoint withName: aString withForm: aForm superManager: aManager
  286.     "create aType FoibleBox at aPoint with form aForm"
  287.  
  288.     | foibleBox |
  289.     foibleBox _ super new.
  290.     foibleBox initializeAt: aPoint withName: aString withForm: aForm superManager: aManager.
  291.     ^foibleBox! !
  292.  
  293.  
  294. !FlowKitBox class methodsFor: 'class initialization'!
  295.  
  296. initialize
  297.     "FlowKitBox initialize"
  298.  
  299.     StyleManager styleName: 'MagnoliaFixed6' baseNames: #('MagnoliaFixed6' ).
  300.     SmallTextStyle _ StyleManager at: 'MagnoliaFixed6'! !
  301.  
  302.  
  303. !FlowKitBox class methodsFor: 'form access'!
  304.  
  305. iconDirectory
  306.     "return the directory that contains the icons for the FlowKit"
  307.  
  308.     ^FlowKitDirectory iconDirectory! !
  309.  
  310.  
  311. "FlowKitBox initialize"!
  312.  
  313.  
  314. FlowKitBox subclass: #BooleanBox
  315.     instanceVariableNames: ''
  316.     classVariableNames: ''
  317.     poolDictionaries: ''
  318.     category: 'FlowKit'!
  319. BooleanBox comment:
  320. 'BooleanBox is the abstract class for Boxes that provide boolean functions'!
  321.  
  322.  
  323. BooleanBox subclass: #AndBox
  324.     instanceVariableNames: ''
  325.     classVariableNames: ''
  326.     poolDictionaries: ''
  327.     category: 'FlowKit'!
  328. AndBox comment:
  329. 'AndBox is the concrete class for Boxes that perform the logical ''and'' function'!
  330.  
  331.  
  332. !AndBox methodsFor: 'initialization'!
  333.  
  334. initializePorts
  335.     "initialize the ports of the FoibleBox"
  336.  
  337.     self inputs: 2 outputs: 1.! !
  338.  
  339. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  340.  
  341. AndBox class
  342.     instanceVariableNames: ''!
  343.  
  344.  
  345. !AndBox class methodsFor: 'class initialization'!
  346.  
  347. initialize
  348.     "AndBox initialize"
  349.  
  350.     formulas _ OrderedCollection with: [:a :b| a and: [b]]! !
  351.  
  352.  
  353. AndBox initialize!
  354.  
  355.  
  356. BooleanBox subclass: #NotBox
  357.     instanceVariableNames: ''
  358.     classVariableNames: ''
  359.     poolDictionaries: ''
  360.     category: 'FlowKit'!
  361. NotBox comment:
  362. 'NotBox is the concrete class for Boxes that perform the logical ''not'' function'!
  363.  
  364.  
  365. !NotBox methodsFor: 'initialization'!
  366.  
  367. initializePorts
  368.     "initialize the ports of the FoibleBox"
  369.  
  370.     self inputs: 1 outputs: 1.! !
  371.  
  372. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  373.  
  374. NotBox class
  375.     instanceVariableNames: ''!
  376.  
  377.  
  378. !NotBox class methodsFor: 'class initialization'!
  379.  
  380. initialize
  381.     "NotBox initialize"
  382.  
  383.     formulas _ OrderedCollection with: [:a | a not]! !
  384.  
  385.  
  386. NotBox initialize!
  387.  
  388.  
  389. BooleanBox subclass: #OrBox
  390.     instanceVariableNames: ''
  391.     classVariableNames: ''
  392.     poolDictionaries: ''
  393.     category: 'FlowKit'!
  394. OrBox comment:
  395. 'OrBox is the concrete class for Boxes that perform the logical ''or'' function'!
  396.  
  397.  
  398. !OrBox methodsFor: 'initialization'!
  399.  
  400. initializePorts
  401.     "initialize the ports of the FoibleBox"
  402.  
  403.     self inputs: 2 outputs: 1.! !
  404.  
  405. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  406.  
  407. OrBox class
  408.     instanceVariableNames: ''!
  409.  
  410.  
  411. !OrBox class methodsFor: 'class initialization'!
  412.  
  413. initialize
  414.     "OrBox initialize"
  415.  
  416.     formulas _ OrderedCollection with: [:a :b| a or: [b]]! !
  417.  
  418.  
  419. OrBox initialize!
  420.  
  421.  
  422. FlowKitBox subclass: #ComparisonBox
  423.     instanceVariableNames: ''
  424.     classVariableNames: ''
  425.     poolDictionaries: ''
  426.     category: 'FlowKit'!
  427. ComparisonBox comment:
  428. 'ComparisonBox is the abstract class for Boxes that compare numbers'!
  429.  
  430.  
  431. ComparisonBox subclass: #NumericComparisonBox
  432.     instanceVariableNames: ''
  433.     classVariableNames: ''
  434.     poolDictionaries: ''
  435.     category: 'FlowKit'!
  436. NumericComparisonBox comment:
  437. 'NumericComparisonBox is the concrete class for Boxes that compare 2 numbers'!
  438.  
  439.  
  440. !NumericComparisonBox methodsFor: 'initialization'!
  441.  
  442. initializePorts
  443.     "initialize the ports of the FoibleBox"
  444.  
  445.     self inputs: 2 outputs: 3.! !
  446.  
  447. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  448.  
  449. NumericComparisonBox class
  450.     instanceVariableNames: ''!
  451.  
  452.  
  453. !NumericComparisonBox class methodsFor: 'class initialization'!
  454.  
  455. initialize
  456.     "NumericComparisonBox initialize"
  457.  
  458.     formulas _ OrderedCollection
  459.                 with: [:a :b | a < b]
  460.                 with: [:a :b | a = b]
  461.                 with: [:a :b | a > b]! !
  462.  
  463.  
  464. NumericComparisonBox initialize!
  465.  
  466.  
  467. ComparisonBox subclass: #ZeroComparisonBox
  468.     instanceVariableNames: ''
  469.     classVariableNames: ''
  470.     poolDictionaries: ''
  471.     category: 'FlowKit'!
  472. ZeroComparisonBox comment:
  473. 'ZeroComparisonBox is the concrete class for Boxes that compare a number to zero'!
  474.  
  475.  
  476. !ZeroComparisonBox methodsFor: 'initialization'!
  477.  
  478. initializePorts
  479.     "initialize the ports of the FoibleBox"
  480.  
  481.      self inputs: 1 outputs: 3! !
  482.  
  483. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  484.  
  485. ZeroComparisonBox class
  486.     instanceVariableNames: ''!
  487.  
  488.  
  489. !ZeroComparisonBox class methodsFor: 'class initialization'!
  490.  
  491. initialize
  492.     "ZeroComparisonBox initialize"
  493.  
  494.     formulas _ OrderedCollection
  495.                 with: [:a | a < 0]
  496.                 with: [:a | a = 0]
  497.                 with: [:a | a > 0]! !
  498.  
  499.  
  500. ZeroComparisonBox initialize!
  501.  
  502.  
  503. FlowKitBox subclass: #ControlBox
  504.     instanceVariableNames: 'manager '
  505.     classVariableNames: ''
  506.     poolDictionaries: ''
  507.     category: 'FlowKit'!
  508. ControlBox comment:
  509. 'ControlBox is the abstract class for Boxes that are control structures.
  510. '!
  511.  
  512.  
  513. !ControlBox methodsFor: 'calculations'!
  514.  
  515. calculateValue: someValues 
  516.     "calculate the receiver's value given the input someValues"
  517.  
  518.     self value: self manager calculate.
  519.      ^self value! !
  520.  
  521.  
  522. !ControlBox methodsFor: 'manager access'!
  523.  
  524. manager 
  525.     "return my companion manager"
  526.  
  527.     ^manager!
  528.  
  529. newManager 
  530.     "return a manager of the type needed by the receiver"
  531.  
  532.     ^self defaultManagerClass newWithBox: self! !
  533.  
  534.  
  535. !ControlBox methodsFor: 'initialization'!
  536.  
  537. addSubBoxes
  538.     "add the initial foible boxes needed for this ConStructBox"
  539.  
  540.     ^self subclassResponsibility!
  541.  
  542. initializeAt: aPoint withName: aName withForm: aForm superManager: aManager
  543.     "initialize the new FoibleBox at aPoint "
  544.     " 10/89 added aManager, so that boxes can know their manager"
  545.     super
  546.         initializeAt: aPoint
  547.         withName: aName
  548.         withForm: aForm
  549.         superManager: aManager.
  550.     manager _ self newManager.
  551.     self addSubBoxes!
  552.  
  553. initializePorts
  554.     "initialize the ports of the FoibleBox"
  555.  
  556.       self inputs: 0 outputs: 0! !
  557.  
  558.  
  559. !ControlBox methodsFor: 'displaying'!
  560.  
  561. displayBox
  562.     "return the area of the receiver that needs to be redrawn 
  563.     during calculations"
  564.  
  565.     ^self manager displayBox! !
  566.  
  567.  
  568. !ControlBox methodsFor: 'comparing'!
  569.  
  570. containsPoint: aPoint 
  571.     "ask the current manager to return the boxes that  
  572.     contain aPoint"
  573.  
  574.     | newBoxes |
  575.     newBoxes _ self manager containsPoint: aPoint.
  576.     newBoxes isEmpty
  577.         ifTrue: [^super containsPoint: aPoint]
  578.         ifFalse: [^newBoxes]! !
  579.  
  580.  
  581. !ControlBox methodsFor: 'displaying-generic'!
  582.  
  583. displayOn: aDisplayMedium at: aDisplayPoint clippingBox: clipRectangle rule: ruleInteger mask: aForm 
  584.     "Ask the current manager to display its boxes"
  585.  
  586.     super
  587.         displayOn: aDisplayMedium
  588.         at: aDisplayPoint
  589.         clippingBox: clipRectangle
  590.         rule: ruleInteger
  591.         mask: aForm.
  592.     "draw outline of box"
  593.     self manager
  594.         displayOn: aDisplayMedium
  595.         at: aDisplayPoint
  596.         clippingBox: clipRectangle
  597.         rule: ruleInteger
  598.         mask: aForm! !
  599.  
  600.  
  601. !ControlBox methodsFor: 'interface tests'!
  602.  
  603. canBeDeleted
  604.     "Return whether I can be deleted"
  605.  
  606.     ^self manager isEmpty! !
  607.  
  608. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  609.  
  610. ControlBox class
  611.     instanceVariableNames: ''!
  612.  
  613.  
  614. !ControlBox class methodsFor: 'form access'!
  615.  
  616. expandableForm
  617.     "create the form for a ConStructBox"
  618.  
  619.     | aRectangle aForm |
  620.     aRectangle _ Rectangle fromUser.
  621.     aForm _ Form new.
  622.     aForm extent: aRectangle extent offset: 0@0.
  623.     aForm borderWidth: 1.
  624.      Sensor cursorPoint: aRectangle origin.
  625.     ^aForm! !
  626.  
  627.  
  628. !ControlBox class methodsFor: 'displaying'!
  629.  
  630. asCursor
  631.     "return an image of the receiver which can be used as a cursor"
  632.  
  633.     ^self expandableForm deepCopy! !
  634.  
  635.  
  636. ControlBox subclass: #ForLoopBox
  637.     instanceVariableNames: ''
  638.     classVariableNames: ''
  639.     poolDictionaries: ''
  640.     category: 'FlowKit'!
  641. ForLoopBox comment:
  642. 'ForLoopBox is the concrete class for Boxes that behave as For Loops'!
  643.  
  644.  
  645. !ForLoopBox methodsFor: 'initialization'!
  646.  
  647. addSubBoxes
  648.     "add the initial foible boxes needed for this ControlBox"
  649.  
  650.     self manager addDecrementBox: self boundingBox.
  651.     self manager addIncrementBox: self boundingBox! !
  652.  
  653.  
  654. !ForLoopBox methodsFor: 'manager access'!
  655.  
  656. defaultManagerClass
  657.     "return a manager of the type needed by the receiver"
  658.  
  659.     ^ForLoopManager! !
  660.  
  661.  
  662. ControlBox subclass: #WhileLoopBox
  663.     instanceVariableNames: ''
  664.     classVariableNames: ''
  665.     poolDictionaries: ''
  666.     category: 'FlowKit'!
  667. WhileLoopBox comment:
  668. 'WhileLoopBox is the concrete class for Boxes that behave as while loops'!
  669.  
  670.  
  671. !WhileLoopBox methodsFor: 'initialization'!
  672.  
  673. addSubBoxes
  674.     "add the initial foible boxes needed for this ControlBox"
  675.  
  676.     self manager addTestBox: self boundingBox.
  677.     self manager addIncrementBox: self boundingBox! !
  678.  
  679.  
  680. !WhileLoopBox methodsFor: 'manager access'!
  681.  
  682. defaultManagerClass
  683.     "return a manager of the type needed by the receiver"
  684.  
  685.     ^WhileLoopManager! !
  686.  
  687.  
  688. FlowKitBox subclass: #FunctionBox
  689.     instanceVariableNames: ''
  690.     classVariableNames: ''
  691.     poolDictionaries: ''
  692.     category: 'FlowKit'!
  693. FunctionBox comment:
  694. 'FunctionBox is the abstract class for Boxes that perform arithmetic functions'!
  695.  
  696.  
  697. !FunctionBox methodsFor: 'initialization'!
  698.  
  699. initializePorts
  700.     "initialize the ports of the FoibleBox"
  701.  
  702.     self inputs: 2 outputs: 1.! !
  703.  
  704.  
  705. FunctionBox subclass: #AdditionBox
  706.     instanceVariableNames: ''
  707.     classVariableNames: ''
  708.     poolDictionaries: ''
  709.     category: 'FlowKit'!
  710. AdditionBox comment:
  711. 'AdditionBox is the concrete class for Boxes that add numbers'!
  712.  
  713. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  714.  
  715. AdditionBox class
  716.     instanceVariableNames: ''!
  717.  
  718.  
  719. !AdditionBox class methodsFor: 'class initialization'!
  720.  
  721. initialize
  722.     "AdditionBox initialize"
  723.  
  724.     formulas _ OrderedCollection with: [:a :b| a + b]! !
  725.  
  726.  
  727. AdditionBox initialize!
  728.  
  729.  
  730. FunctionBox subclass: #IntegerDivisionBox
  731.     instanceVariableNames: ''
  732.     classVariableNames: ''
  733.     poolDictionaries: ''
  734.     category: 'FlowKit'!
  735. IntegerDivisionBox comment:
  736. 'IntegerDivisionBox is the concrete class for Boxes that perform integer division'!
  737.  
  738.  
  739. !IntegerDivisionBox methodsFor: 'initialization'!
  740.  
  741. initializePorts
  742.     "initialize the ports of the FoibleBox"
  743.  
  744.     self inputs: 2 outputs: 2.! !
  745.  
  746. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  747.  
  748. IntegerDivisionBox class
  749.     instanceVariableNames: ''!
  750.  
  751.  
  752. !IntegerDivisionBox class methodsFor: 'class initialization'!
  753.  
  754. initialize
  755.     "IntegerDivisionBox initialize"
  756.  
  757.     formulas _ OrderedCollection with: [:a :b | a rem: b]
  758.                 with: [:a :b | a quo: b]! !
  759.  
  760.  
  761. IntegerDivisionBox initialize!
  762.  
  763.  
  764. FunctionBox subclass: #MaxBox
  765.     instanceVariableNames: ''
  766.     classVariableNames: ''
  767.     poolDictionaries: ''
  768.     category: 'FlowKit'!
  769. MaxBox comment:
  770. 'MaxBox is the concrete class for Boxes that perform the maximum function'!
  771.  
  772. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  773.  
  774. MaxBox class
  775.     instanceVariableNames: ''!
  776.  
  777.  
  778. !MaxBox class methodsFor: 'class initialization'!
  779.  
  780. initialize
  781.     "MaxBox initialize"
  782.  
  783.     formulas _ OrderedCollection with: [:a :b| a max: b]! !
  784.  
  785.  
  786. MaxBox initialize!
  787.  
  788.  
  789. FunctionBox subclass: #MinBox
  790.     instanceVariableNames: ''
  791.     classVariableNames: ''
  792.     poolDictionaries: ''
  793.     category: 'FlowKit'!
  794. MinBox comment:
  795. 'MinBox is the concrete class for Boxes that perform the minimum function'!
  796.  
  797. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  798.  
  799. MinBox class
  800.     instanceVariableNames: ''!
  801.  
  802.  
  803. !MinBox class methodsFor: 'class initialization'!
  804.  
  805. initialize
  806.     "MinBox initialize"
  807.  
  808.     formulas _ OrderedCollection with: [:a :b| a min: b]! !
  809.  
  810.  
  811. MinBox initialize!
  812.  
  813.  
  814. FunctionBox subclass: #MultiplicationBox
  815.     instanceVariableNames: ''
  816.     classVariableNames: ''
  817.     poolDictionaries: ''
  818.     category: 'FlowKit'!
  819. MultiplicationBox comment:
  820. 'MultiplicationBox is the concrete class for Boxes that multiply numbers'!
  821.  
  822. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  823.  
  824. MultiplicationBox class
  825.     instanceVariableNames: ''!
  826.  
  827.  
  828. !MultiplicationBox class methodsFor: 'class initialization'!
  829.  
  830. initialize
  831.     "MultiplicationBox initialize"
  832.  
  833.     formulas _ OrderedCollection with: [:a :b | a * b]! !
  834.  
  835.  
  836. MultiplicationBox initialize!
  837.  
  838.  
  839. FunctionBox subclass: #RealDivisionBox
  840.     instanceVariableNames: ''
  841.     classVariableNames: ''
  842.     poolDictionaries: ''
  843.     category: 'FlowKit'!
  844. RealDivisionBox comment:
  845. 'RealDivisionBox is the concrete class for Boxes that perform real number division'!
  846.  
  847. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  848.  
  849. RealDivisionBox class
  850.     instanceVariableNames: ''!
  851.  
  852.  
  853. !RealDivisionBox class methodsFor: 'class initialization'!
  854.  
  855. initialize
  856.     "RealDivisionBox initialize"
  857.  
  858.     formulas _ OrderedCollection with: [:a :b| a / b]! !
  859.  
  860.  
  861. RealDivisionBox initialize!
  862.  
  863.  
  864. FunctionBox subclass: #SubtractionBox
  865.     instanceVariableNames: ''
  866.     classVariableNames: ''
  867.     poolDictionaries: ''
  868.     category: 'FlowKit'!
  869. SubtractionBox comment:
  870. 'SubtractionBox is the concrete class for Boxes that  subtract numbers'!
  871.  
  872. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  873.  
  874. SubtractionBox class
  875.     instanceVariableNames: ''!
  876.  
  877.  
  878. !SubtractionBox class methodsFor: 'class initialization'!
  879.  
  880. initialize
  881.     "SubtractionBox initialize"
  882.  
  883.     formulas _ OrderedCollection with: [:a :b | a - b]! !
  884.  
  885.  
  886. SubtractionBox initialize!
  887.  
  888.  
  889. FlowKitBox subclass: #InputBox
  890.     instanceVariableNames: ''
  891.     classVariableNames: ''
  892.     poolDictionaries: ''
  893.     category: 'FlowKit'!
  894. InputBox comment:
  895. 'InputBox is the abstract class for Boxes that accept user input'!
  896.  
  897.  
  898. !InputBox methodsFor: 'initialization'!
  899.  
  900. initializePorts
  901.     "initialize the ports of the FoibleBox"
  902.  
  903.     self inputs: 0 outputs: 1! !
  904.  
  905.  
  906. !InputBox methodsFor: 'calculations'!
  907.  
  908. outputResults: results 
  909.     "display the results of the receiver's calculation, InputBox
  910.       sends its single result to all of its Output Ports"
  911.  
  912.     self displayValue: results.
  913.     (1 to: outputPort size)
  914.         do: [:i | (outputPort at: i)
  915.                 token: (results at: 1)]! !
  916.  
  917.  
  918. !InputBox methodsFor: 'port access'!
  919.  
  920. findOutputPort: aPoint 
  921.     "find and return an output port that can be linked to at        
  922.         aPoint, InputBox can accept an infinite number of outgoing links"
  923.  
  924.     | newPort result ports aRectangle |
  925.     result _ super findOutputPort: aPoint.
  926.     result isNil
  927.         ifTrue: 
  928.             [ports _ outputPort select: [:each | each boundingBox containsPoint: aPoint].
  929.             ports isEmpty
  930.                 ifTrue: [^nil]
  931.                 ifFalse: 
  932.                     [newPort _ (ports at: 1) shallowCopy.
  933.                     newPort link: nil.
  934.                     outputPort add: newPort.
  935.                     ^newPort]]
  936.         ifFalse: [^result]! !
  937.  
  938.  
  939. !InputBox methodsFor: 'interface tests'!
  940.  
  941. canAcceptInput
  942.     "input boxes accept input by default"
  943.  
  944.     ^true!
  945.  
  946. canBeCopied
  947.     "Return whether I can be copied"
  948.  
  949.     ^false! !
  950.  
  951.  
  952. InputBox subclass: #BooleanInputBox
  953.     instanceVariableNames: ''
  954.     classVariableNames: ''
  955.     poolDictionaries: ''
  956.     category: 'FlowKit'!
  957.  
  958.  
  959. !BooleanInputBox methodsFor: 'initialization'!
  960.  
  961. initializeAt: aPoint withName: aName withForm: aForm superManager: aManager 
  962.     "initialize the new FoibleBox at aPoint"
  963.  
  964.     super
  965.         initializeAt: aPoint
  966.         withName: aName
  967.         withForm: aForm
  968.         superManager: aManager.
  969.     self initValue: (OrderedCollection with: false)! !
  970.  
  971.  
  972. !BooleanInputBox methodsFor: 'accessing'!
  973.  
  974. acceptInput: aPoint 
  975.     "return opposite of current value"
  976.  
  977.     ^self value first not!
  978.  
  979. firstValue: aValue 
  980.     "set the first value of the receiver"
  981.  
  982.     self value at: 1 put: aValue.
  983.     self displayValue!
  984.  
  985. newInputFromUser: aValue 
  986.     "inform the receiver that he has new input from the user"
  987.  
  988.     self firstValue: aValue.
  989.     ^self boundingBox!
  990.  
  991. value: aValue 
  992.     "set the value of the receiver"
  993.  
  994.     value _ aValue.
  995.     self displayValue! !
  996.  
  997.  
  998. !BooleanInputBox methodsFor: 'form access'!
  999.  
  1000. addInput: aValue toForm: aForm 
  1001.     "display aValue on aForm and return it"
  1002.  
  1003.     aValue
  1004.         ifTrue: 
  1005.             [self class onButtonForm displayOn: aForm at: 0 @ 0.
  1006.             ^aForm]
  1007.         ifFalse: [^aForm].!
  1008.  
  1009. inputForm
  1010.     "return a copy of the receiver's form with the current input 
  1011.      displayed"
  1012.  
  1013.     | aForm |
  1014.     aForm _ self baseForm.
  1015.     aForm offset: 0@0.
  1016.     ^self addInput: self firstValue toForm: aForm!
  1017.  
  1018. inputForm: aValue 
  1019.     "return a copy of the receiver's form with aValue  
  1020.     displayed on it"
  1021.  
  1022.     | aForm |
  1023.     aForm _ self baseForm.
  1024.     aForm offset: 0@0.
  1025.     ^self addInput: aValue toForm: aForm! !
  1026.  
  1027.  
  1028. !BooleanInputBox methodsFor: 'displaying'!
  1029.  
  1030. displayValue
  1031.     "displays the receiver's current value"
  1032.  
  1033.     self removeAllForms.
  1034.     forms add: self inputForm! !
  1035.  
  1036. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1037.  
  1038. BooleanInputBox class
  1039.     instanceVariableNames: ''!
  1040.  
  1041.  
  1042. !BooleanInputBox class methodsFor: 'accessing'!
  1043.  
  1044. companionClass
  1045.     "return the class of my companion Box"
  1046.  
  1047.     ^DummyBooleanInputBox! !
  1048.  
  1049.  
  1050. BooleanInputBox subclass: #BooleanArrowsInput
  1051.     instanceVariableNames: ''
  1052.     classVariableNames: ''
  1053.     poolDictionaries: ''
  1054.     category: 'FlowKit'!
  1055.  
  1056. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1057.  
  1058. BooleanArrowsInput class
  1059.     instanceVariableNames: 'onButtonForm '!
  1060.  
  1061.  
  1062. !BooleanArrowsInput class methodsFor: 'class initialization'!
  1063.  
  1064. initialize
  1065.     "BooleanArrowsInput initialize"
  1066.  
  1067.     formulas _ OrderedCollection with: [:value | value]! !
  1068.  
  1069.  
  1070. !BooleanArrowsInput class methodsFor: 'accessing'!
  1071.  
  1072. onButtonForm
  1073.     "return the on form class instance variable"
  1074.  
  1075.     onButtonForm isNil ifTrue: [onButtonForm _ self getIcon: 'BooleanArrows.on'].
  1076.     ^onButtonForm! !
  1077.  
  1078.  
  1079. !BooleanArrowsInput class methodsFor: 'form access'!
  1080.  
  1081. baseForm
  1082.     "Return the form for this class"
  1083.  
  1084.     myForm isNil ifTrue: [myForm _ self getIcon: 'BooleanArrows']. 
  1085.     ^myForm deepCopy! !
  1086.  
  1087.  
  1088. BooleanArrowsInput initialize!
  1089.  
  1090.  
  1091. BooleanInputBox subclass: #BooleanHandInput
  1092.     instanceVariableNames: ''
  1093.     classVariableNames: ''
  1094.     poolDictionaries: ''
  1095.     category: 'FlowKit'!
  1096.  
  1097. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1098.  
  1099. BooleanHandInput class
  1100.     instanceVariableNames: 'onButtonForm '!
  1101.  
  1102.  
  1103. !BooleanHandInput class methodsFor: 'class initialization'!
  1104.  
  1105. initialize
  1106.     "BooleanHandInput initialize"
  1107.  
  1108.     formulas _ OrderedCollection with: [:value | value]! !
  1109.  
  1110.  
  1111. !BooleanHandInput class methodsFor: 'accessing'!
  1112.  
  1113. onButtonForm
  1114.     "return the on form class instance variable"
  1115.  
  1116.     onButtonForm isNil ifTrue: [onButtonForm _ self getIcon: 'BooleanHand.on'].
  1117.     ^onButtonForm! !
  1118.  
  1119.  
  1120. !BooleanHandInput class methodsFor: 'form access'!
  1121.  
  1122. baseForm
  1123.     "Return the form for this class"
  1124.  
  1125.     myForm isNil ifTrue: [myForm _ self getIcon: 'BooleanHand']. 
  1126.     ^myForm deepCopy! !
  1127.  
  1128.  
  1129. BooleanHandInput initialize!
  1130.  
  1131.  
  1132. BooleanInputBox subclass: #BooleanLightInput
  1133.     instanceVariableNames: ''
  1134.     classVariableNames: ''
  1135.     poolDictionaries: ''
  1136.     category: 'FlowKit'!
  1137.  
  1138. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1139.  
  1140. BooleanLightInput class
  1141.     instanceVariableNames: 'onButtonForm '!
  1142.  
  1143.  
  1144. !BooleanLightInput class methodsFor: 'class initialization'!
  1145.  
  1146. initialize
  1147.     "BooleanLightInput initialize"
  1148.  
  1149.     formulas _ OrderedCollection with: [:value | value]! !
  1150.  
  1151.  
  1152. !BooleanLightInput class methodsFor: 'accessing'!
  1153.  
  1154. onButtonForm
  1155.     "return the on form class instance variable"
  1156.  
  1157.     onButtonForm isNil ifTrue: [onButtonForm _ self getIcon: 'BooleanLight.on'].
  1158.     ^onButtonForm! !
  1159.  
  1160.  
  1161. !BooleanLightInput class methodsFor: 'form access'!
  1162.  
  1163. baseForm
  1164.     "Return the form for this class"
  1165.  
  1166.     myForm isNil ifTrue: [myForm _ self getIcon: 'BooleanLight']. 
  1167.     ^myForm deepCopy! !
  1168.  
  1169.  
  1170. BooleanLightInput initialize!
  1171.  
  1172.  
  1173. InputBox subclass: #DummyBooleanInputBox
  1174.     instanceVariableNames: ''
  1175.     classVariableNames: ''
  1176.     poolDictionaries: ''
  1177.     category: 'FlowKit'!
  1178.  
  1179.  
  1180. !DummyBooleanInputBox methodsFor: 'calculations'!
  1181.  
  1182. value
  1183.     "return the value of the receiver"
  1184.  
  1185.     ^self companion value! !
  1186.  
  1187.  
  1188. !DummyBooleanInputBox methodsFor: 'interface tests'!
  1189.  
  1190. canAcceptInput
  1191.     "dummy input boxes don't allow input"
  1192.  
  1193.     ^false! !
  1194.  
  1195. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1196.  
  1197. DummyBooleanInputBox class
  1198.     instanceVariableNames: ''!
  1199.  
  1200.  
  1201. !DummyBooleanInputBox class methodsFor: 'class initialization'!
  1202.  
  1203. initialize
  1204.     "DummyBooleanInputBox initialize"
  1205.  
  1206.     formulas _ OrderedCollection with: [:value | value]! !
  1207.  
  1208.  
  1209. DummyBooleanInputBox initialize!
  1210.  
  1211.  
  1212. InputBox subclass: #DummyNumericInputBox
  1213.     instanceVariableNames: ''
  1214.     classVariableNames: ''
  1215.     poolDictionaries: ''
  1216.     category: 'FlowKit'!
  1217. DummyNumericInputBox comment:
  1218. 'DummyNumericInputBox is the concrete class for Boxes that serve as place markers in the back view for NumericInputBoxes'!
  1219.  
  1220.  
  1221. !DummyNumericInputBox methodsFor: 'calculations'!
  1222.  
  1223. value
  1224.     "return the value of the receiver"
  1225.  
  1226.     ^self companion value! !
  1227.  
  1228.  
  1229. !DummyNumericInputBox methodsFor: 'interface tests'!
  1230.  
  1231. canAcceptInput
  1232.     "dummy input boxes don't allow input"
  1233.  
  1234.     ^false! !
  1235.  
  1236. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1237.  
  1238. DummyNumericInputBox class
  1239.     instanceVariableNames: ''!
  1240.  
  1241.  
  1242. !DummyNumericInputBox class methodsFor: 'class initialization'!
  1243.  
  1244. initialize
  1245.     "StaticNumericInputBox initialize"
  1246.  
  1247.     formulas _ OrderedCollection with: [:box | box firstValue]! !
  1248.  
  1249.  
  1250. DummyNumericInputBox initialize!
  1251.  
  1252.  
  1253. InputBox subclass: #NumericInputBox
  1254.     instanceVariableNames: ''
  1255.     classVariableNames: ''
  1256.     poolDictionaries: ''
  1257.     category: 'FlowKit'!
  1258. NumericInputBox comment:
  1259. 'NumericInputBox is the concrete class for Boxes that accept numeric input from the user'!
  1260.  
  1261.  
  1262. !NumericInputBox methodsFor: 'initialization'!
  1263.  
  1264. initializeAt: aPoint withName: aName withForm: aForm superManager: aManager
  1265.     "initialize the new FoibleBox at aPoint"
  1266.  
  1267.     super
  1268.         initializeAt: aPoint
  1269.         withName: aName
  1270.         withForm: aForm
  1271.         superManager: aManager.
  1272.     self initValue: (OrderedCollection with: 0)! !
  1273.  
  1274.  
  1275. !NumericInputBox methodsFor: 'accessing'!
  1276.  
  1277. firstValue: aValue 
  1278.     "set the first value of the receiver"
  1279.  
  1280.     self value at: 1 put: aValue.
  1281.     self displayValue!
  1282.  
  1283. initValue: aValue 
  1284.     "store the receiver's initial value"
  1285.  
  1286.     self value: aValue.
  1287.     self displayValue!
  1288.  
  1289. newInputFromUser: aValue 
  1290.     "inform the receiver that he has new input from the user"
  1291.  
  1292.     aValue size > 0
  1293.         ifTrue: 
  1294.             [self firstValue: aValue asNumber.
  1295.             ^self boundingBox]
  1296.         ifFalse: [^'Box must have a number, please try again']!
  1297.  
  1298. value: aValue 
  1299.     "set the value of the receiver"
  1300.  
  1301.     value _ aValue.
  1302.     self displayValue! !
  1303.  
  1304.  
  1305. !NumericInputBox methodsFor: 'form access'!
  1306.  
  1307. addInput: aNumber toForm: aForm 
  1308.     "display aValue on aForm and return it"
  1309.     "Write the number aNumber to aForm    
  1310.     NOTE: Hard-coded routine: assumes 50x18 boxes"
  1311.  
  1312.     | aNumberString aString |
  1313.     aNumberString _ aNumber printString.
  1314.     
  1315.     (aNumberString asDisplayText textStyle: SmallTextStyle)
  1316.         displayOn: aForm at: 4 @ 4.
  1317.     ^aForm!
  1318.  
  1319. inputForm
  1320.     "return a copy of the receiver's form with the current input 
  1321.      displayed"
  1322.  
  1323.     | aForm |
  1324.     aForm _ self baseForm.
  1325.     aForm offset: 0@0.
  1326.     ^self addInput: self firstValue toForm: aForm! !
  1327.  
  1328.  
  1329. !NumericInputBox methodsFor: 'displaying'!
  1330.  
  1331. displayValue
  1332.     "displays the receiver's current value"
  1333.  
  1334.     self removeAllForms.
  1335.     forms add: self inputForm! !
  1336.  
  1337. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1338.  
  1339. NumericInputBox class
  1340.     instanceVariableNames: ''!
  1341.  
  1342.  
  1343. !NumericInputBox class methodsFor: 'accessing'!
  1344.  
  1345. companionClass
  1346.     "return the class of my companion Box"
  1347.  
  1348.     ^DummyNumericInputBox! !
  1349.  
  1350.  
  1351. !NumericInputBox class methodsFor: 'class initialization'!
  1352.  
  1353. initialize
  1354.     "NumericInputBox initialize"
  1355.  
  1356.     formulas _ OrderedCollection with: [:box | box firstValue]! !
  1357.  
  1358.  
  1359. NumericInputBox initialize!
  1360.  
  1361.  
  1362. NumericInputBox subclass: #DigitalTunerInputBox
  1363.     instanceVariableNames: 'increment '
  1364.     classVariableNames: 'DecreaseRect IncreaseRect '
  1365.     poolDictionaries: ''
  1366.     category: 'FlowKit'!
  1367.  
  1368.  
  1369. !DigitalTunerInputBox methodsFor: 'interface tests'!
  1370.  
  1371. canBeCalibrated
  1372.     "increment of digital tuner can be adjusted"
  1373.  
  1374.     ^true! !
  1375.  
  1376.  
  1377. !DigitalTunerInputBox methodsFor: 'form access'!
  1378.  
  1379. addInput: aNumber toForm: aForm 
  1380.     "display aValue on aForm and return it"
  1381.  
  1382.     | aNumberString aString | 
  1383.     aNumberString _ aNumber printString.
  1384.     
  1385.     (aNumberString asDisplayText textStyle: SmallTextStyle)
  1386.         displayOn: aForm at: 7 @ 15.
  1387.     ^aForm! !
  1388.  
  1389.  
  1390. !DigitalTunerInputBox methodsFor: 'accessing'!
  1391.  
  1392. acceptInput: aPoint 
  1393.     "increment or decrement the tuner if appropriate buttons    
  1394.     are pressed"
  1395.  
  1396.     (DecreaseRect containsPoint: aPoint)
  1397.         ifTrue: [^self value first - self increment].
  1398.     (IncreaseRect containsPoint: aPoint)
  1399.         ifTrue: [^self value first + self increment].
  1400.     ^self value first!
  1401.  
  1402. calibrate
  1403.     "allow user to set tuner increment"
  1404.  
  1405.     | newIncrement |
  1406.     newIncrement _ FillInTheBlank request: 'Enter increment for tuner:' initialAnswer: self increment printString.
  1407.     self increment: newIncrement asNumber!
  1408.  
  1409. increment
  1410.     "return the current tuner increment"
  1411.  
  1412.     ^increment!
  1413.  
  1414. increment: aValue
  1415.     "set the current tuner increment"
  1416.  
  1417.     increment _ aValue!
  1418.  
  1419. newInputFromUser: aValue 
  1420.     "inform the receiver that he has new input from the user"
  1421.  
  1422.     self firstValue: aValue.
  1423.     ^self boundingBox! !
  1424.  
  1425.  
  1426. !DigitalTunerInputBox methodsFor: 'initialization'!
  1427.  
  1428. initializeAt: aPoint withName: aName withForm: aForm superManager: aManager 
  1429.     "initialize the new FoibleBox at aPoint"
  1430.  
  1431.     self initializeIncrement.
  1432.     super
  1433.         initializeAt: aPoint
  1434.         withName: aName
  1435.         withForm: aForm
  1436.         superManager: aManager!
  1437.  
  1438. initializeIncrement
  1439.     "initialize the tuning increment"
  1440.  
  1441.     increment _ 1! !
  1442.  
  1443. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1444.  
  1445. DigitalTunerInputBox class
  1446.     instanceVariableNames: ''!
  1447.  
  1448.  
  1449. !DigitalTunerInputBox class methodsFor: 'class initialization'!
  1450.  
  1451. initialize
  1452.     "DigitalTunerInputBox initialize"
  1453.  
  1454.     DecreaseRect _ Rectangle origin: 4 @ 30 corner: 24 @ 42.
  1455.     IncreaseRect _ Rectangle origin: 27 @ 30 corner: 47 @ 42.
  1456.     formulas _ OrderedCollection with: [:box | box firstValue]! !
  1457.  
  1458.  
  1459. DigitalTunerInputBox initialize!
  1460.  
  1461.  
  1462. NumericInputBox subclass: #RandomNumberInputBox
  1463.     instanceVariableNames: 'rand max '
  1464.     classVariableNames: ''
  1465.     poolDictionaries: ''
  1466.     category: 'FlowKit'!
  1467.  
  1468.  
  1469. !RandomNumberInputBox methodsFor: 'initialization'!
  1470.  
  1471. initializeAt: aPoint withName: aName withForm: aForm superManager: aManager 
  1472.     "initialize the new FoibleBox at aPoint"
  1473.  
  1474.     super
  1475.         initializeAt: aPoint
  1476.         withName: aName
  1477.         withForm: aForm
  1478.         superManager: aManager.
  1479.     self initializeStream.
  1480.     self initValue: (OrderedCollection with: (self acceptInput: 0@0))!
  1481.  
  1482. initializeStream
  1483.     "create a Random stream for the input box and set initial maximum"
  1484.  
  1485.     rand _ Random new.
  1486.     max _ 50! !
  1487.  
  1488.  
  1489. !RandomNumberInputBox methodsFor: 'accessing'!
  1490.  
  1491. acceptInput: aPoint
  1492.     "get the next number in the random stream"
  1493.  
  1494.     ^(self rand next * max) truncated + 1!
  1495.  
  1496. calibrate
  1497.     "allow user to set the maximum value for the random number"
  1498.  
  1499.     | newMax |
  1500.     newMax _ FillInTheBlank request: 'Enter maximum random value:' initialAnswer: self max printString.
  1501.     self max: newMax asNumber!
  1502.  
  1503. max
  1504.     "get the upper limit for this random box"
  1505.  
  1506.     ^max!
  1507.  
  1508. max: aValue
  1509.     "set the upper limit for this random box"
  1510.  
  1511.     max _ aValue!
  1512.  
  1513. newInputFromUser: aValue 
  1514.     "inform the receiver that he has new input from the user"
  1515.  
  1516.     self firstValue: aValue.
  1517.     ^self boundingBox!
  1518.  
  1519. rand
  1520.     "return the stream for this instance"
  1521.  
  1522.     ^rand! !
  1523.  
  1524.  
  1525. !RandomNumberInputBox methodsFor: 'form access'!
  1526.  
  1527. addInput: aNumber toForm: aForm 
  1528.     "display aValue on aForm and return it"
  1529.  
  1530.     | aNumberString aString |
  1531.     aNumberString _ aNumber printString.
  1532.     
  1533.     (aNumberString asDisplayText textStyle: SmallTextStyle)
  1534.         displayOn: aForm at: 7 @ 37.
  1535.     ^aForm! !
  1536.  
  1537.  
  1538. !RandomNumberInputBox methodsFor: 'interface tests'!
  1539.  
  1540. canBeCalibrated
  1541.     "max of random number box can be adjusted"
  1542.  
  1543.     ^true! !
  1544.  
  1545. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1546.  
  1547. RandomNumberInputBox class
  1548.     instanceVariableNames: ''!
  1549.  
  1550.  
  1551. !RandomNumberInputBox class methodsFor: 'class initialization'!
  1552.  
  1553. initialize
  1554.     "RandomNumberInputBox initialize"
  1555.  
  1556.     formulas _ OrderedCollection with: [:box | box firstValue]! !
  1557.  
  1558.  
  1559. RandomNumberInputBox initialize!
  1560.  
  1561.  
  1562. NumericInputBox subclass: #SliderInputBox
  1563.     instanceVariableNames: 'min max increment knobForm knobPosition prevXValue '
  1564.     classVariableNames: ''
  1565.     poolDictionaries: ''
  1566.     category: 'FlowKit'!
  1567.  
  1568.  
  1569. !SliderInputBox methodsFor: 'interface tests'!
  1570.  
  1571. canBeCalibrated
  1572.     "max and min of slider can be adjusted"
  1573.  
  1574.     ^true! !
  1575.  
  1576.  
  1577. !SliderInputBox methodsFor: 'form access'!
  1578.  
  1579. addInput: aNumber toForm: aForm 
  1580.     "display aValue on aForm and return it"
  1581.  
  1582.     | aNumberString aString |
  1583.     aNumberString _ aNumber printString.
  1584.     
  1585.     (aNumberString asDisplayText textStyle: SmallTextStyle)
  1586.         displayOn: aForm at: 5 @ 112.
  1587.     self knob 
  1588.     displayOn: aForm 
  1589.     at: self knobPosition.
  1590.     "self knob moveTo: self knobPosition + (aForm offset) restoring: aForm. <-- doesn't work"
  1591.     ^aForm! !
  1592.  
  1593.  
  1594. !SliderInputBox methodsFor: 'private'!
  1595.  
  1596. adjustKnobPosition
  1597.     "reset the position of the slider knob"
  1598.  
  1599.     | knobLocation range |
  1600.     
  1601.     knobLocation _ (self value first - self min) abs.
  1602.     range _ self max - self min.
  1603.     knobLocation _ (knobLocation / range * 100 asFloat) rounded.
  1604.     (self value first >= self max or: [knobLocation > 100])
  1605.         ifTrue: 
  1606.             [knobLocation _ 100.
  1607.             self value at: 1 put: self max].
  1608.     self value first <= self min
  1609.         ifTrue: 
  1610.             [knobLocation _ 0.
  1611.             self value at: 1 put: self min].
  1612.     knobLocation _ 100 - knobLocation.
  1613.     knobPosition y: knobLocation!
  1614.  
  1615. canDecrease
  1616.     "answer true if not at minimum"
  1617.  
  1618.     self value first <= self min ifTrue: [^false].
  1619.     ^true!
  1620.  
  1621. canIncrease
  1622.     "answer true if not at maximum"
  1623.  
  1624.     self value first >= self max ifTrue: [^false].
  1625.     ^true!
  1626.  
  1627. changeKnobPositionBy: aValue 
  1628.     "set the position of the slider knob"
  1629.  
  1630.     | oldY newY |
  1631.     oldY _ knobPosition y.
  1632.     newY _ oldY + aValue.
  1633.     knobPosition y: newY! !
  1634.  
  1635.  
  1636. !SliderInputBox methodsFor: 'accessing'!
  1637.  
  1638. acceptInput: aPoint 
  1639.     | knobRect |
  1640.     knobRect _ Rectangle origin: self knobPosition extent: 15 @ 15.
  1641.     (knobRect containsPoint: aPoint)
  1642.         ifTrue: [prevXValue > aPoint x & self canDecrease
  1643.                 ifTrue: 
  1644.                     [self changeKnobPositionBy: 2.
  1645.                     ^self value first + self increment negated]
  1646.                 ifFalse: [prevXValue < aPoint x  & self canIncrease
  1647.                         ifTrue: 
  1648.                             [self changeKnobPositionBy: -2.
  1649.                             ^self value first + self increment]]].
  1650.     prevXValue _ aPoint x.
  1651.     ^self value first!
  1652.  
  1653. calibrate
  1654.     "allow user to set the maximum and minimum values for  
  1655.     the slider"
  1656.  
  1657.     | newMax newMin newRange |
  1658.     
  1659.     newMin _ FillInTheBlank request: 'Enter minimum for device:' initialAnswer: self min printString.
  1660.     self min: newMin asNumber.
  1661.     newMax _ FillInTheBlank request: 'Enter maximum for device:' initialAnswer: self max printString.
  1662.     self max: newMax asNumber.
  1663.     newRange _ self max - self min.
  1664.     self increment: (newRange / 50) asFloat.
  1665.     self adjustKnobPosition!
  1666.  
  1667. increment
  1668.     "answer the current slider increment"
  1669.  
  1670.     ^increment!
  1671.  
  1672. increment: aValue
  1673.     "set the current slider increment"
  1674.  
  1675.     increment _ aValue!
  1676.  
  1677. knob
  1678.     "answer the form of the slider knob"
  1679.  
  1680.     ^knobForm!
  1681.  
  1682. knobPosition
  1683.     "answer the position of the slider knob"
  1684.  
  1685.     ^knobPosition!
  1686.  
  1687. knobPosition: aPoint
  1688.     "set the position of the slider knob"
  1689.  
  1690.     knobPosition _ aPoint!
  1691.  
  1692. max
  1693.     "answer the slider maximum"
  1694.  
  1695.     ^max!
  1696.  
  1697. max: aValue
  1698.     "set the slider maximum"
  1699.  
  1700.     max _ aValue!
  1701.  
  1702. min
  1703.     "answer the slider minimum"
  1704.  
  1705.     ^min!
  1706.  
  1707. min: aValue
  1708.     "set the slider minimum"
  1709.  
  1710.     min _ aValue!
  1711.  
  1712. newInputFromUser: aValue 
  1713.     "inform the receiver that he has new input from the user"
  1714.  
  1715.     self firstValue: aValue.
  1716.     ^self boundingBox! !
  1717.  
  1718.  
  1719. !SliderInputBox methodsFor: 'initialization'!
  1720.  
  1721. initializeAt: aPoint withName: aName withForm: aForm superManager: aManager 
  1722.     "initialize the new FoibleBox at aPoint"
  1723.  
  1724.     self initializeSlider.
  1725.     super
  1726.         initializeAt: aPoint
  1727.         withName: aName
  1728.         withForm: aForm
  1729.         superManager: aManager!
  1730.  
  1731. initializeSlider
  1732.     "initialize the slider variables"
  1733.  
  1734.     self max: 50.
  1735.     self min: 0.
  1736.     self increment: 1.
  1737.     prevXValue _ 100.
  1738.     knobForm _ Form extent: 12@7.
  1739.     knobForm borderWidth: 2 mask: Form black.
  1740.     knobPosition _ 18 @ 100! !
  1741.  
  1742. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1743.  
  1744. SliderInputBox class
  1745.     instanceVariableNames: ''!
  1746.  
  1747.  
  1748. !SliderInputBox class methodsFor: 'class initialization'!
  1749.  
  1750. initialize
  1751.     "SliderInputBox initialize"
  1752.  
  1753.     formulas _ OrderedCollection with: [:box | box firstValue]! !
  1754.  
  1755.  
  1756. SliderInputBox initialize!
  1757.  
  1758.  
  1759. FlowKitBox subclass: #LabelBox
  1760.     instanceVariableNames: 'label '
  1761.     classVariableNames: ''
  1762.     poolDictionaries: ''
  1763.     category: 'FlowKit'!
  1764. LabelBox comment:
  1765. 'LabelBox is the concrete class for Boxes that serve as labels
  1766.  
  1767. The instance variable label holds the label of the LabelBox'!
  1768.  
  1769.  
  1770. !LabelBox methodsFor: 'initialization'!
  1771.  
  1772. initializeAt: aPoint withName: aName withForm: aForm superManager: aManager
  1773.     "initialize the new FoibleBox at aPoint"
  1774.  
  1775.     super
  1776.         initializeAt: aPoint
  1777.         withName: aName
  1778.         withForm: aForm
  1779.         superManager: aManager.
  1780.     self initValue: (OrderedCollection with: '')!
  1781.  
  1782. initializePorts
  1783.     "initialize the ports of the FoibleBox"
  1784.  
  1785.     self inputs: 0 outputs: 0! !
  1786.  
  1787.  
  1788. !LabelBox methodsFor: 'accessing'!
  1789.  
  1790. firstValue: aValue 
  1791.     "set the first value of the receiver"
  1792.  
  1793.     self value at: 1 put: aValue.
  1794.     self displayValue!
  1795.  
  1796. initValue: aValue 
  1797.     "store the receiver's initial value"
  1798.  
  1799.     self value: aValue.
  1800.     self displayValue!
  1801.  
  1802. newInputFromUser: aValue 
  1803.     "inform the receiver that he has new input from the user"
  1804.  
  1805.     self firstValue: aValue.
  1806.     ^self boundingBox!
  1807.  
  1808. value: aValue 
  1809.     "set the value of the receiver"
  1810.  
  1811.     value _ aValue.
  1812.     self displayValue! !
  1813.  
  1814.  
  1815. !LabelBox methodsFor: 'displaying'!
  1816.  
  1817. displayValue
  1818.     "display the label string of the receiver"
  1819.  
  1820.     self removeAllForms.
  1821.     forms add: self inputForm! !
  1822.  
  1823.  
  1824. !LabelBox methodsFor: 'form access'!
  1825.  
  1826. addInput: aString toForm: aForm 
  1827.     "Write the string aString to aForm      
  1828.     NOTE: Hard-coded routine: assumes 50x18 boxes, Manolia 6  font"
  1829.  
  1830.     (aString asDisplayText textStyle: SmallTextStyle)
  1831.         displayOn: aForm at: 2 @ 4.
  1832.     ^aForm!
  1833.  
  1834. inputForm
  1835.     "Return a copy of the receiver's form with the current label 
  1836.     string displayed"
  1837.  
  1838.     | aForm aText |
  1839.     aForm _ self baseForm.
  1840.     aForm offset: 0@0.
  1841.     ^self addInput: self firstValue toForm: aForm! !
  1842.  
  1843.  
  1844. !LabelBox methodsFor: 'interface tests'!
  1845.  
  1846. canAcceptInput
  1847.     "label boxes accept input"
  1848.  
  1849.     ^true! !
  1850.  
  1851. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1852.  
  1853. LabelBox class
  1854.     instanceVariableNames: ''!
  1855.  
  1856.  
  1857. !LabelBox class methodsFor: 'displaying'!
  1858.  
  1859. asCursor
  1860.     "return an image of the receiver which can be used as a cursor"
  1861.  
  1862.     ^self expandableForm deepCopy! !
  1863.  
  1864.  
  1865. !LabelBox class methodsFor: 'form access'!
  1866.  
  1867. expandableForm
  1868.     "create the form for a ConStructBox"
  1869.  
  1870.     | aRectangle aForm |
  1871.     aRectangle _ Rectangle fromUser.
  1872.     aForm _ Form new.
  1873.     aForm extent: aRectangle extent offset: 0@0.
  1874.     aForm borderWidth: 1.
  1875.      Sensor cursorPoint: aRectangle origin.
  1876.     ^aForm! !
  1877.  
  1878.  
  1879. FlowKitBox subclass: #LoopControlBox
  1880.     instanceVariableNames: ''
  1881.     classVariableNames: ''
  1882.     poolDictionaries: ''
  1883.     category: 'FlowKit'!
  1884. LoopControlBox comment:
  1885. 'LoopControlBox is the abstract class for Boxes that behave as loop control variables for ControlBoxes'!
  1886.  
  1887.  
  1888. !LoopControlBox methodsFor: 'calculations'!
  1889.  
  1890. masterCalculateValue: someValues 
  1891.     "calculate the receiver's value given the input someValues"
  1892.  
  1893.     self subclassResponsibility!
  1894.  
  1895. masterToken
  1896.     "the sender, an input port, has received a new value for  
  1897.     use in the         
  1898.     receiver's calculation"
  1899.  
  1900.     | values results |
  1901.     values _ self getInputValues.
  1902.     values isNil ifTrue: [^nil].
  1903.     results _ self masterCalculateValue: values.
  1904.     self outputResults: results! !
  1905.  
  1906.  
  1907. !LoopControlBox methodsFor: 'interface tests'!
  1908.  
  1909. canBeDeleted
  1910.     "Return whether I can be deleted"
  1911.  
  1912.     ^false!
  1913.  
  1914. canMoveIndependently
  1915.     "Return whether I can move at the user's request"
  1916.  
  1917.     ^false! !
  1918.  
  1919.  
  1920. LoopControlBox subclass: #DecrementBox
  1921.     instanceVariableNames: ''
  1922.     classVariableNames: ''
  1923.     poolDictionaries: ''
  1924.     category: 'FlowKit'!
  1925. DecrementBox comment:
  1926. 'DecrementBox is the concrete class for Boxes that serve as counter variables for ForLoopBoxes, counting down to zero'!
  1927.  
  1928.  
  1929. !DecrementBox methodsFor: 'initialization'!
  1930.  
  1931. initializePorts
  1932.     "initialize the ports of the FoibleBox"
  1933.  
  1934.     self inputs: 1 outputs: 1.! !
  1935.  
  1936.  
  1937. !DecrementBox methodsFor: 'calculations'!
  1938.  
  1939. calculateValue: someValues 
  1940.     "calculate the receiver's value given the input someValues"
  1941.  
  1942.     self value isNil ifTrue: [self value: someValues].
  1943.     ^self value!
  1944.  
  1945. masterCalculateValue: someValues 
  1946.     "calculate the receiver's value given the input someValues"
  1947.  
  1948.     self firstValue: self firstValue - 1.
  1949.     ^self value! !
  1950.  
  1951.  
  1952. LoopControlBox subclass: #IncrementBox
  1953.     instanceVariableNames: ''
  1954.     classVariableNames: ''
  1955.     poolDictionaries: ''
  1956.     category: 'FlowKit'!
  1957. IncrementBox comment:
  1958. 'IncrementBox is the concrete class for Boxes that serve as counter variables for ControlBoxes, counting up from zero'!
  1959.  
  1960.  
  1961. !IncrementBox methodsFor: 'initialization'!
  1962.  
  1963. initializePorts
  1964.     "initialize the ports of the FoibleBox"
  1965.  
  1966.     self inputs: 0 outputs: 1.! !
  1967.  
  1968.  
  1969. !IncrementBox methodsFor: 'calculations'!
  1970.  
  1971. calculateValue: someValues 
  1972.     "calculate the receiver's value given the input someValues"
  1973.  
  1974.     self value isNil ifTrue: [self value: (OrderedCollection with: 0)].
  1975.     ^self value!
  1976.  
  1977. masterCalculateValue: someValues 
  1978.     "calculate the receiver's value given the input someValues"
  1979.  
  1980.     self firstValue: self firstValue + 1.
  1981.     ^self value! !
  1982.  
  1983.  
  1984. LoopControlBox subclass: #ShiftRegBox
  1985.     instanceVariableNames: ''
  1986.     classVariableNames: ''
  1987.     poolDictionaries: ''
  1988.     category: 'FlowKit'!
  1989. ShiftRegBox comment:
  1990. 'ShiftRegBox is the abstract class for Shift Register Boxes'!
  1991.  
  1992.  
  1993. !ShiftRegBox methodsFor: 'initialization'!
  1994.  
  1995. initializePorts
  1996.     "initialize the ports of the FoibleBox"
  1997.  
  1998.     self inputs: 1 outputs: 1! !
  1999.  
  2000. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2001.  
  2002. ShiftRegBox class
  2003.     instanceVariableNames: ''!
  2004.  
  2005.  
  2006. !ShiftRegBox class methodsFor: 'form access'!
  2007.  
  2008. baseForm
  2009.     "Return the form for this class"
  2010.  
  2011.     myForm isNil ifTrue: [myForm _ self getIcon: 'ShiftRegBox'].
  2012.     ^myForm deepCopy! !
  2013.  
  2014.  
  2015. ShiftRegBox subclass: #LeftShiftRegBox
  2016.     instanceVariableNames: ''
  2017.     classVariableNames: ''
  2018.     poolDictionaries: ''
  2019.     category: 'FlowKit'!
  2020. LeftShiftRegBox comment:
  2021. 'LeftShiftRegBox is the concrete class for Shift Register Boxes that reside on the left side of ControlBoxes '!
  2022.  
  2023.  
  2024. !LeftShiftRegBox methodsFor: 'calculations'!
  2025.  
  2026. masterCalculateValue: someValues 
  2027.     "calculate the receiver's value given the input someValues"
  2028.  
  2029.     self value: someValues.
  2030.     ^self value!
  2031.  
  2032. token
  2033.     "the sender, an input port, has received a new value for   
  2034.     use in the          
  2035.     receiver's calculation"
  2036.     "ignore this message"
  2037.  
  2038.     ^self! !
  2039.  
  2040.  
  2041. ShiftRegBox subclass: #RightShiftRegBox
  2042.     instanceVariableNames: ''
  2043.     classVariableNames: ''
  2044.     poolDictionaries: ''
  2045.     category: 'FlowKit'!
  2046. RightShiftRegBox comment:
  2047. 'LeftShiftRegBox is the concrete class for Shift Register Boxes that reside on the left side of ControlBoxes '!
  2048.  
  2049.  
  2050. !RightShiftRegBox methodsFor: 'calculations'!
  2051.  
  2052. calculateValue: someValues 
  2053.     "calculate the receiver's value given the input someValues"
  2054.  
  2055.     self value isNil ifTrue: [self value: someValues]. 
  2056.     ^self value!
  2057.  
  2058. masterCalculateValue: someValues 
  2059.     "calculate the receiver's value given the input someValues"
  2060.  
  2061.     | aValue |
  2062.      companion masterToken.
  2063.     aValue _ companion value.
  2064.     aValue isNil ifFalse: [self value: companion value].
  2065.     ^self value! !
  2066.  
  2067.  
  2068. LoopControlBox subclass: #TestBox
  2069.     instanceVariableNames: ''
  2070.     classVariableNames: ''
  2071.     poolDictionaries: ''
  2072.     category: 'FlowKit'!
  2073. TestBox comment:
  2074. 'TestBox is the concrete class for Boxes that serve as the boolean test variables that provide loop control for WhileLoopBoxes'!
  2075.  
  2076.  
  2077. !TestBox methodsFor: 'calculations'!
  2078.  
  2079. calculateValue: someValues 
  2080.     "calculate the receiver's value given the input someValues"
  2081.  
  2082.     self value: someValues.
  2083.     ^self value! !
  2084.  
  2085.  
  2086. !TestBox methodsFor: 'initialization'!
  2087.  
  2088. initializePorts
  2089.     "initialize the ports of the FoibleBox"
  2090.  
  2091.     self inputs: 1 outputs: 1! !
  2092.  
  2093.  
  2094. FlowKitBox subclass: #OutputBox
  2095.     instanceVariableNames: ''
  2096.     classVariableNames: ''
  2097.     poolDictionaries: ''
  2098.     category: 'FlowKit'!
  2099. OutputBox comment:
  2100. 'OutputBox is the abstract class for Boxes that display values'!
  2101.  
  2102.  
  2103. !OutputBox methodsFor: 'initialization'!
  2104.  
  2105. initializePorts
  2106.     "initialize the ports of the FoibleBox"
  2107.  
  2108.     self inputs: 1 outputs: 1.! !
  2109.  
  2110.  
  2111. !OutputBox methodsFor: 'displaying'!
  2112.  
  2113. displayBox
  2114.     "returns the area of the receiver to redisplay to reflect the current calculations"
  2115.  
  2116.     ^self boundingBox! !
  2117.  
  2118.  
  2119. !OutputBox methodsFor: 'calculations'!
  2120.  
  2121. outputResults: results 
  2122.     "display the results of the receiver's calculation, OutputBox
  2123.       sends its single result to all of its Output Ports"
  2124.  
  2125.     self displayValue: results.
  2126.     (1 to: outputPort size)
  2127.         do: [:i | (outputPort at: i)
  2128.                 token: (results at: 1)]! !
  2129.  
  2130.  
  2131. !OutputBox methodsFor: 'port access'!
  2132.  
  2133. findOutputPort: aPoint 
  2134.     "find and return an output port that can be linked to at        
  2135.         aPoint, OutputBox can accept an infinite number of outgoing links"
  2136.  
  2137.     | newPort result ports aRectangle |
  2138.     result _ super findOutputPort: aPoint.
  2139.     result isNil
  2140.         ifTrue: 
  2141.             [ports _ outputPort select: [:each | each boundingBox containsPoint: aPoint].
  2142.             ports isEmpty
  2143.                 ifTrue: [^nil]
  2144.                 ifFalse: 
  2145.                     [newPort _ (ports at: 1) shallowCopy.
  2146.                     newPort link: nil.
  2147.                     outputPort add: newPort.
  2148.                     ^newPort]]
  2149.         ifFalse: [^result]! !
  2150.  
  2151.  
  2152. !OutputBox methodsFor: 'interface tests'!
  2153.  
  2154. canBeCopied
  2155.     "Return whether I can be copied"
  2156.  
  2157.     ^false! !
  2158.  
  2159.  
  2160. OutputBox subclass: #BooleanOutputBox
  2161.     instanceVariableNames: ''
  2162.     classVariableNames: ''
  2163.     poolDictionaries: ''
  2164.     category: 'FlowKit'!
  2165. BooleanOutputBox comment:
  2166. 'BooleanOutputBox is an abstract class for Boxes that display boolean values.
  2167. Concrete classes must provide an initialization message to set up the initial
  2168. and "on" forms. '!
  2169.  
  2170.  
  2171. !BooleanOutputBox methodsFor: 'displaying'!
  2172.  
  2173. displayValue: someValues 
  2174.     "display the value of a Boolean Output Box during 
  2175.     calculations "
  2176.  
  2177.     self removeAllForms.
  2178.     forms add: (self inputForm: (someValues at: 1))! !
  2179.  
  2180.  
  2181. !BooleanOutputBox methodsFor: 'form access'!
  2182.  
  2183. addInput: aValue toForm: aForm 
  2184.     "display aValue on aForm and return it"
  2185.  
  2186.     aValue
  2187.         ifTrue: 
  2188.             [self class onButtonForm displayOn: aForm at: 0 @ 0.
  2189.             ^aForm]
  2190.         ifFalse: [^aForm]!
  2191.  
  2192. inputForm: aValue 
  2193.     "return a copy of the receiver's form with aValue  
  2194.     displayed on it"
  2195.  
  2196.     | aForm aText |
  2197.     aForm _ self baseForm.
  2198.     aForm offset: 0@0.
  2199.     ^self addInput: aValue toForm: aForm! !
  2200.  
  2201. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2202.  
  2203. BooleanOutputBox class
  2204.     instanceVariableNames: ''!
  2205. BooleanOutputBox class comment:
  2206. 'The class instance variable onButtonForm holds the form that
  2207. is displayed when the BooleanOutputBox has a true value'!
  2208.  
  2209.  
  2210. !BooleanOutputBox class methodsFor: 'accessing'!
  2211.  
  2212. companionClass
  2213.     "return the class of my companion Box"
  2214.  
  2215.     ^DummyBooleanOutputBox! !
  2216.  
  2217.  
  2218. BooleanOutputBox subclass: #BooleanArrows
  2219.     instanceVariableNames: ''
  2220.     classVariableNames: ''
  2221.     poolDictionaries: ''
  2222.     category: 'FlowKit'!
  2223.  
  2224. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2225.  
  2226. BooleanArrows class
  2227.     instanceVariableNames: 'onButtonForm '!
  2228.  
  2229.  
  2230. !BooleanArrows class methodsFor: 'class initialization'!
  2231.  
  2232. initialize
  2233.     "BooleanArrows initialize"
  2234.  
  2235.     formulas _ OrderedCollection with: [:value | value]! !
  2236.  
  2237.  
  2238. !BooleanArrows class methodsFor: 'accessing'!
  2239.  
  2240. onButtonForm
  2241.     "return the on form class instance variable"
  2242.  
  2243.     onButtonForm isNil ifTrue: [onButtonForm _ self getIcon: self name,'.on'].
  2244.     ^onButtonForm! !
  2245.  
  2246.  
  2247. BooleanArrows initialize!
  2248.  
  2249.  
  2250. BooleanOutputBox subclass: #BooleanHand
  2251.     instanceVariableNames: ''
  2252.     classVariableNames: ''
  2253.     poolDictionaries: ''
  2254.     category: 'FlowKit'!
  2255.  
  2256. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2257.  
  2258. BooleanHand class
  2259.     instanceVariableNames: 'onButtonForm '!
  2260.  
  2261.  
  2262. !BooleanHand class methodsFor: 'class initialization'!
  2263.  
  2264. initialize
  2265.     "BooleanHand initialize"
  2266.  
  2267.     formulas _ OrderedCollection with: [:value | value]! !
  2268.  
  2269.  
  2270. !BooleanHand class methodsFor: 'accessing'!
  2271.  
  2272. onButtonForm
  2273.     "return the on form class instance variable"
  2274.  
  2275.     onButtonForm isNil ifTrue: [onButtonForm _ self getIcon: self name,'.on'].
  2276.     ^onButtonForm! !
  2277.  
  2278.  
  2279. BooleanHand initialize!
  2280.  
  2281.  
  2282. BooleanOutputBox subclass: #BooleanLight
  2283.     instanceVariableNames: ''
  2284.     classVariableNames: ''
  2285.     poolDictionaries: ''
  2286.     category: 'FlowKit'!
  2287.  
  2288. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2289.  
  2290. BooleanLight class
  2291.     instanceVariableNames: 'onButtonForm '!
  2292.  
  2293.  
  2294. !BooleanLight class methodsFor: 'class initialization'!
  2295.  
  2296. initialize
  2297.     "BooleanLight initialize"
  2298.  
  2299.     formulas _ OrderedCollection with: [:value | value]! !
  2300.  
  2301.  
  2302. !BooleanLight class methodsFor: 'accessing'!
  2303.  
  2304. onButtonForm
  2305.     "return the on form class instance variable"
  2306.  
  2307.     onButtonForm isNil ifTrue: [onButtonForm _ self getIcon: self name,'.on'].
  2308.     ^onButtonForm! !
  2309.  
  2310.  
  2311. BooleanLight initialize!
  2312.  
  2313.  
  2314. OutputBox subclass: #DummyBooleanOutputBox
  2315.     instanceVariableNames: ''
  2316.     classVariableNames: ''
  2317.     poolDictionaries: ''
  2318.     category: 'FlowKit'!
  2319. DummyBooleanOutputBox comment:
  2320. 'DummyBooleanOutputBox is the concrete class for Boxes that serve as place markers in the back view for BooleanOutputBoxes'!
  2321.  
  2322.  
  2323. !DummyBooleanOutputBox methodsFor: 'calculations'!
  2324.  
  2325. token
  2326.     "the sender, an input port, has received a new value for  
  2327.     use in the receiver's calculation and the receiver's 
  2328.     companion "
  2329.  
  2330.     super token.
  2331.     self companion displayValue: self value! !
  2332.  
  2333. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2334.  
  2335. DummyBooleanOutputBox class
  2336.     instanceVariableNames: ''!
  2337.  
  2338.  
  2339. !DummyBooleanOutputBox class methodsFor: 'class initialization'!
  2340.  
  2341. initialize
  2342.     "DummyBooleanOutputBox initialize"
  2343.  
  2344.     formulas _ OrderedCollection with: [:value | value]! !
  2345.  
  2346.  
  2347. DummyBooleanOutputBox initialize!
  2348.  
  2349.  
  2350. OutputBox subclass: #DummyNumericOutputBox
  2351.     instanceVariableNames: ''
  2352.     classVariableNames: ''
  2353.     poolDictionaries: ''
  2354.     category: 'FlowKit'!
  2355. DummyNumericOutputBox comment:
  2356. 'DummyNumericOutputBox is the concrete class for Boxes that serve as place markers in the back view for NumericOutputBoxes'!
  2357.  
  2358.  
  2359. !DummyNumericOutputBox methodsFor: 'calculations'!
  2360.  
  2361. token
  2362.     "the sender, an input port, has received a new value for  
  2363.     use in the receiver's calculation and the receiver's 
  2364.     companion "
  2365.  
  2366.     super token.
  2367.     self companion displayValue: self value! !
  2368.  
  2369. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2370.  
  2371. DummyNumericOutputBox class
  2372.     instanceVariableNames: ''!
  2373.  
  2374.  
  2375. !DummyNumericOutputBox class methodsFor: 'class initialization'!
  2376.  
  2377. initialize
  2378.     "StaticNumericOutputBox initialize"
  2379.  
  2380.     formulas _ OrderedCollection with: [:value | value]! !
  2381.  
  2382.  
  2383. DummyNumericOutputBox initialize!
  2384.  
  2385.  
  2386. OutputBox subclass: #NumericOutputBox
  2387.     instanceVariableNames: ''
  2388.     classVariableNames: ''
  2389.     poolDictionaries: ''
  2390.     category: 'FlowKit'!
  2391. NumericOutputBox comment:
  2392. 'NumericOutputBox is the concrete class for Boxes that display numbers'!
  2393.  
  2394.  
  2395. !NumericOutputBox methodsFor: 'displaying'!
  2396.  
  2397. displayValue: someNumbers 
  2398.     "display the value of a Numeric Output Box during  
  2399.     calculations"
  2400.  
  2401.     self removeAllForms.
  2402.     forms add: (self inputForm: (someNumbers at: 1))! !
  2403.  
  2404.  
  2405. !NumericOutputBox methodsFor: 'form access'!
  2406.  
  2407. addInput: aNumber toForm: aForm 
  2408.     "display aValue on aForm and return it"
  2409.     "Write the number aNumber to aForm    
  2410.     NOTE: Hard-coded routine: assumes 50x18 boxes, Manolia 6  font"
  2411.  
  2412.     | aNumberString aString |
  2413.     aNumberString _ aNumber printString.
  2414.     
  2415.     (aNumberString asDisplayText textStyle: SmallTextStyle)
  2416.         displayOn: aForm at: 4 @ 4.
  2417.     ^aForm!
  2418.  
  2419. inputForm: aNumber 
  2420.     "return a copy of the receiver's form with aNumber  
  2421.        displayed on it"
  2422.  
  2423.     | aForm aText |
  2424.     aForm _ self baseForm.
  2425.     aForm offset: 0@0.
  2426.     ^self addInput: aNumber toForm: aForm! !
  2427.  
  2428. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2429.  
  2430. NumericOutputBox class
  2431.     instanceVariableNames: ''!
  2432.  
  2433.  
  2434. !NumericOutputBox class methodsFor: 'class initialization'!
  2435.  
  2436. initialize
  2437.     "NumericOutputBox initialize"
  2438.  
  2439.     formulas _ OrderedCollection with: [:value |  value]! !
  2440.  
  2441.  
  2442. !NumericOutputBox class methodsFor: 'accessing'!
  2443.  
  2444. companionClass
  2445.     "return the class of my companion Box"
  2446.  
  2447.     ^DummyNumericOutputBox! !
  2448.  
  2449.  
  2450. NumericOutputBox initialize!
  2451.  
  2452.  
  2453. NumericOutputBox subclass: #ScaledNumericOutputBox
  2454.     instanceVariableNames: 'max min '
  2455.     classVariableNames: ''
  2456.     poolDictionaries: ''
  2457.     category: 'FlowKit'!
  2458.  
  2459.  
  2460. !ScaledNumericOutputBox methodsFor: 'initialization'!
  2461.  
  2462. initializeAt: aPoint withName: aName withForm: aForm superManager: aManager
  2463.     "initialize the new FoibleBox at aPoint"
  2464.  
  2465.     super
  2466.         initializeAt: aPoint
  2467.         withName: aName
  2468.         withForm: aForm
  2469.         superManager: aManager.
  2470.     self initializeRange!
  2471.  
  2472. initializeRange 
  2473.     "initialize the max and min of the output device"
  2474.  
  2475.     self max: 100.
  2476.     self min: 0! !
  2477.  
  2478.  
  2479. !ScaledNumericOutputBox methodsFor: 'accessing'!
  2480.  
  2481. calibrate
  2482.     "allow user to set the maximum and minimum values for 
  2483.     the output device"
  2484.  
  2485.     | newMax newMin |
  2486.     newMin _ FillInTheBlank request: 'Enter minimum for device:' initialAnswer: self min printString.
  2487.     self min: newMin asNumber.
  2488.     newMax _ FillInTheBlank request: 'Enter maximum for device:' initialAnswer: self max printString.
  2489.     self max: newMax asNumber!
  2490.  
  2491. max
  2492.     "get the upper limit for this device"
  2493.  
  2494.     ^max!
  2495.  
  2496. max: aValue
  2497.     "set the upper limit for this device"
  2498.  
  2499.     max _ aValue!
  2500.  
  2501. min
  2502.     "get the lower limit for this device"
  2503.  
  2504.     ^min!
  2505.  
  2506. min: aValue
  2507.     "set the lower limit for this device"
  2508.  
  2509.     min _ aValue! !
  2510.  
  2511.  
  2512. !ScaledNumericOutputBox methodsFor: 'interface tests'!
  2513.  
  2514. canBeCalibrated
  2515.     "max and min of scaled devices can be adjusted"
  2516.  
  2517.     ^true! !
  2518.  
  2519.  
  2520. !ScaledNumericOutputBox methodsFor: 'scaling'!
  2521.  
  2522. scaleNumericValue: aNumber
  2523.     "answer a value scaled for display"
  2524.  
  2525.     self subclassResponsibility! !
  2526.  
  2527.  
  2528. ScaledNumericOutputBox subclass: #AnalogMeterOutputBox
  2529.     instanceVariableNames: ''
  2530.     classVariableNames: ''
  2531.     poolDictionaries: ''
  2532.     category: 'FlowKit'!
  2533.  
  2534.  
  2535. !AnalogMeterOutputBox methodsFor: 'form access'!
  2536.  
  2537. addInput: aNumber toForm: aForm 
  2538.     "convert the output to number for display"
  2539.  
  2540.     | pos aLine x y |
  2541.     pos _ self scaleNumericValue: aNumber.
  2542.     x _ (pos * 6 - 135) degreesToRadians cos.
  2543.     y _ (pos * 6 - 135) degreesToRadians sin.
  2544.     aLine _ Line
  2545.                 from: 0 @ 0
  2546.                 to: x @ y * 35
  2547.                 withForm: (Form dotOfSize: 2).
  2548.     aLine displayOn: aForm at: 30 @ 52.
  2549.     ^aForm! !
  2550.  
  2551.  
  2552. !AnalogMeterOutputBox methodsFor: 'scaling'!
  2553.  
  2554. scaleNumericValue: aNumber 
  2555.     "answer the position of the meter hand as a number between 1 and 15"
  2556.  
  2557.     | range adjustedNumber |
  2558.     aNumber < self min
  2559.         ifTrue: [^0]
  2560.         ifFalse: 
  2561.             [adjustedNumber _ (aNumber - self min) abs.
  2562.             range _ self max - self min. 
  2563.             ^15 min: (adjustedNumber / range * 15 asFloat) rounded]! !
  2564.  
  2565.  
  2566. !AnalogMeterOutputBox methodsFor: 'initialization'!
  2567.  
  2568. initializeAt: aPoint withName: aName withForm: aForm superManager: aManager 
  2569.     "initialize the new FoibleBox at aPoint"
  2570.  
  2571.     
  2572.     super
  2573.         initializeAt: aPoint
  2574.         withName: aName
  2575.         withForm: aForm
  2576.         superManager: aManager.
  2577.     
  2578.     self displayValue: (OrderedCollection with: 1).! !
  2579.  
  2580. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2581.  
  2582. AnalogMeterOutputBox class
  2583.     instanceVariableNames: ''!
  2584.  
  2585.  
  2586. !AnalogMeterOutputBox class methodsFor: 'class initialization'!
  2587.  
  2588. initialize
  2589.     "AnalogMeterOutputBox initialize"
  2590.  
  2591.     formulas _ OrderedCollection with: [:value |  value]! !
  2592.  
  2593.  
  2594. AnalogMeterOutputBox initialize!
  2595.  
  2596.  
  2597. ScaledNumericOutputBox subclass: #LEDMeterOutputBox
  2598.     instanceVariableNames: ''
  2599.     classVariableNames: ''
  2600.     poolDictionaries: ''
  2601.     category: 'FlowKit'!
  2602.  
  2603.  
  2604. !LEDMeterOutputBox methodsFor: 'form access'!
  2605.  
  2606. addInput: aNumber toForm: aForm 
  2607.     "convert the output to number of LEDs and light that 
  2608.     number "
  2609.  
  2610.     | leds aRect |
  2611.     leds _ self scaleNumericValue: aNumber.
  2612.     aRect _ Rectangle origin: (9 @ 21) extent: 8 @ 9. 
  2613.     1 to: 10 do: 
  2614.         [:x | 
  2615.         x <= leds
  2616.             ifTrue: [aForm fill: aRect mask: Form darkGray]
  2617.             ifFalse: [aForm fill: aRect mask: Form white].
  2618.         aRect moveBy: 10 @ 0].
  2619.     ^aForm! !
  2620.  
  2621.  
  2622. !LEDMeterOutputBox methodsFor: 'scaling'!
  2623.  
  2624. scaleNumericValue: aNumber 
  2625.     "answer the number of LEDs to light"
  2626.  
  2627.     | range adjustedNumber |
  2628.     aNumber < self min
  2629.         ifTrue: [^0]
  2630.         ifFalse: 
  2631.             [adjustedNumber _ (aNumber - self min) abs.
  2632.             range _ self max - self min. 
  2633.             ^(adjustedNumber / range * 10 asFloat) rounded]! !
  2634.  
  2635. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2636.  
  2637. LEDMeterOutputBox class
  2638.     instanceVariableNames: ''!
  2639.  
  2640.  
  2641. !LEDMeterOutputBox class methodsFor: 'class initialization'!
  2642.  
  2643. initialize
  2644.     "LEDMeterOutputBox initialize"
  2645.  
  2646.     formulas _ OrderedCollection with: [:value |  value]! !
  2647.  
  2648.  
  2649. LEDMeterOutputBox initialize!
  2650.  
  2651.  
  2652. ScaledNumericOutputBox subclass: #PlottedOutputBox
  2653.     instanceVariableNames: 'plotQueue '
  2654.     classVariableNames: ''
  2655.     poolDictionaries: ''
  2656.     category: 'FlowKit'!
  2657.  
  2658.  
  2659. !PlottedOutputBox methodsFor: 'form access'!
  2660.  
  2661. addInput: aNumber toForm: aForm 
  2662.     "convert the output to new point on plot, display plot 
  2663.     queue of values"
  2664.  
  2665.     | newValue aLinearFit position plotForm |
  2666.     
  2667.     self addToPlotQueue: aNumber.
  2668.     plotForm _ Form new extent: 2 @ 2.
  2669.     plotForm black.
  2670.     aLinearFit _ LinearFit new.
  2671.     aLinearFit form: plotForm.
  2672.     position _ 0.
  2673.     plotQueue do: 
  2674.         [:x | (x notNil) ifTrue: [newValue _ self scaleNumericValue: x].
  2675.         aLinearFit add: position @ newValue.
  2676.         position _ position + 15].
  2677.     aLinearFit displayOn: aForm at: 0 @ 0.
  2678.     ^aForm! !
  2679.  
  2680.  
  2681. !PlottedOutputBox methodsFor: 'scaling'!
  2682.  
  2683. scaleNumericValue: aNumber 
  2684.     "answer a value between 1 and 80"
  2685.  
  2686.     | range adjustedNumber |
  2687.     aNumber < self min
  2688.         ifTrue: [^0]
  2689.         ifFalse: 
  2690.             [adjustedNumber _ (aNumber - self min) abs.
  2691.             range _ self max - self min.
  2692.             ^80 - (adjustedNumber / range * 80 asFloat) rounded]! !
  2693.  
  2694.  
  2695. !PlottedOutputBox methodsFor: 'private'!
  2696.  
  2697. addToPlotQueue: aNumber 
  2698.     "add the new value to the plot queue"
  2699.  
  2700.     plotQueue add: aNumber.
  2701.     plotQueue size > 11 ifTrue: [plotQueue removeFirst]! !
  2702.  
  2703.  
  2704. !PlottedOutputBox methodsFor: 'initialization'!
  2705.  
  2706. initializeRange
  2707.     "initialize the max and min of the output device"
  2708.  
  2709.     self max: 100.
  2710.     self min: 0.
  2711.     plotQueue _ OrderedCollection new: 1.
  2712.     plotQueue add: 50! !
  2713.  
  2714. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2715.  
  2716. PlottedOutputBox class
  2717.     instanceVariableNames: ''!
  2718.  
  2719.  
  2720. !PlottedOutputBox class methodsFor: 'class initialization'!
  2721.  
  2722. initialize
  2723.     "PlottedOutputBox initialize"
  2724.  
  2725.     formulas _ OrderedCollection with: [:value |  value]! !
  2726.  
  2727.  
  2728. PlottedOutputBox initialize!
  2729.  
  2730.  
  2731. FoibleLink subclass: #WiringLink
  2732.     instanceVariableNames: ''
  2733.     classVariableNames: ''
  2734.     poolDictionaries: ''
  2735.     category: 'FlowKit'!
  2736. WiringLink comment:
  2737. 'WiringLink is the concrete class of all Links in FlowKit'!
  2738.  
  2739.  
  2740. !WiringLink methodsFor: 'interface tests'!
  2741.  
  2742. acceptsDataLinks: aPoint 
  2743.     "Return whether I accept DataLinks 
  2744.      at the user interface"
  2745.  
  2746.     ^false!
  2747.  
  2748. canAcceptInput
  2749.     "just say no to input requests for wires"
  2750.  
  2751.     ^false!
  2752.  
  2753. canMoveDependently
  2754.     "Return whether I can be moved when I am in a Control box being moved"
  2755.  
  2756.     ^false!
  2757.  
  2758. givesDataLinks: aPoint
  2759.     "Return whether I give DataLinks
  2760.          at the user interface"
  2761.  
  2762.     ^false! !
  2763.  
  2764.  
  2765. !WiringLink methodsFor: 'calculations'!
  2766.  
  2767. initValue: aValue 
  2768.     "ignore this message, it is for boxes only"
  2769.  
  2770.     ^self!
  2771.  
  2772. token: aValue 
  2773.     "the receiver has a new value, pass the value to its destination port"
  2774.  
  2775.     destination token: aValue! !
  2776.  
  2777.  
  2778. !WiringLink methodsFor: 'accessing'!
  2779.  
  2780. companion
  2781.     "ignore this message, it is for boxes only"
  2782.  
  2783.     ^nil! !
  2784.  
  2785.  
  2786. !WiringLink methodsFor: 'displaying'!
  2787.  
  2788. displayBox
  2789.     "answers nil, indicating the receiver does not display its 
  2790.     value during calculations"
  2791.  
  2792.     ^nil! !
  2793.  
  2794. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2795.  
  2796. WiringLink class
  2797.     instanceVariableNames: ''!
  2798.  
  2799.  
  2800. !WiringLink class methodsFor: 'form access'!
  2801.  
  2802. iconDirectory
  2803.     "return the directory that contains the icons for the FlowKit"
  2804.  
  2805.     ^FlowKitDirectory iconDirectory! !
  2806.  
  2807.  
  2808. FoibleManager subclass: #FlowKitManager
  2809.     instanceVariableNames: ''
  2810.     classVariableNames: ''
  2811.     poolDictionaries: ''
  2812.     category: 'FlowKit'!
  2813. FlowKitManager comment:
  2814. 'FlowKitManager is the concrete class for managers'!
  2815.  
  2816.  
  2817. !FlowKitManager methodsFor: 'accessing'!
  2818.  
  2819. changeValue: name to: newInput 
  2820.     "Inform the Box with the given name that it has new input"
  2821.  
  2822.     | box |
  2823.     box _ self findName: name.
  2824.     box isNil ifTrue: [^nil].
  2825.     ^box newInputFromUser: newInput!
  2826.  
  2827. lastBox
  2828.     "returns the last box added to to the receiver"
  2829.  
  2830.     ^boxes last! !
  2831.  
  2832.  
  2833. !FlowKitManager methodsFor: 'displaying'!
  2834.  
  2835. displayBox
  2836.     "returns the area of the manager's box that needs to be 
  2837.     redrawn during calculations"
  2838.  
  2839.     | aBox aRectangle |
  2840.     boxes do: 
  2841.         [:each | 
  2842.         aBox _ each displayBox.
  2843.         aRectangle isNil
  2844.             ifTrue: [aRectangle _ aBox]
  2845.             ifFalse: [aBox isNil ifFalse: [aRectangle _ aRectangle merge: aBox]]].
  2846.     ^aRectangle! !
  2847.  
  2848.  
  2849. !FlowKitManager methodsFor: 'calculations'!
  2850.  
  2851. calculate
  2852.     "start calculations of all of the receiver's boxes"
  2853.  
  2854.     boxes do: [:each | (each isKindOf: InputBox)
  2855.             ifTrue: [each token]].
  2856.     boxes do: [:each | (each isKindOf: ControlBox)
  2857.             ifTrue: [each token]].
  2858.     ^nil! !
  2859.  
  2860.  
  2861. !FlowKitManager methodsFor: 'adding'!
  2862.  
  2863. add: aClass at: aPoint 
  2864.     "add a Foible of the class aClass at aPoint"
  2865.  
  2866.     ^self addBox: [:name | aClass
  2867.             offset: aPoint
  2868.             withName: name
  2869.             withForm: aClass asCursor
  2870.             superManager: self]! !
  2871.  
  2872.  
  2873. FlowKitManager subclass: #ControlBoxManager
  2874.     instanceVariableNames: 'inputs leftShiftReg rightShiftReg incrementBox '
  2875.     classVariableNames: ''
  2876.     poolDictionaries: ''
  2877.     category: 'FlowKit'!
  2878. ControlBoxManager comment:
  2879. 'ControlBoxManager is the concrete class for managers of ControlBoxes.
  2880.  
  2881. Instance Variables:
  2882.  
  2883. inputs is a collection of boxes that must have input before a
  2884. ControlBoxManager can execute its subprogram
  2885.  
  2886. leftShiftReg and rightShiftReg are collections, respectively, of
  2887. leftShiftRegBoxes and rightShiftRegBoxes in the ControlBoxManager''s
  2888. subprogram
  2889.  
  2890. incrementBox is the ''i'' box in the ControlBoxManager''s subprogram
  2891. '!
  2892.  
  2893.  
  2894. !ControlBoxManager methodsFor: 'accessing'!
  2895.  
  2896. addInput: aBox 
  2897.     "add aBox to the set of inputs of the receiver"
  2898.  
  2899.     inputs isNil ifTrue: [inputs _ OrderedCollection new].
  2900.     inputs add: aBox!
  2901.  
  2902. inputs
  2903.     "return the collection of inputs for this box"
  2904.  
  2905.     ^inputs! !
  2906.  
  2907.  
  2908. !ControlBoxManager methodsFor: 'adding'!
  2909.  
  2910. addIncrementBox: aRectangle 
  2911.     "add increment box"
  2912.  
  2913.     incrementBox _ IncrementBox
  2914.                 offset: aRectangle origin + (aRectangle extent x // 8 @ (3 * (aRectangle extent y // 4)))
  2915.                 withName: 'i'
  2916.                 withForm: IncrementBox asCursor
  2917.                 superManager: self.
  2918.     incrementBox initializePorts.
  2919.     boxes add: incrementBox!
  2920.  
  2921. addShiftRegTo: aRectangle 
  2922.     "add a shift register in the area aRectangle"
  2923.  
  2924. | left right leftNum rightNum newLeftShiftReg newRightShiftReg name stream |
  2925.     leftShiftReg isNil ifTrue: [leftShiftReg _ OrderedCollection new].
  2926.     rightShiftReg isNil ifTrue: [rightShiftReg _ OrderedCollection new].
  2927.     leftNum _ 20 * leftShiftReg size.
  2928.     rightNum _ 20 * rightShiftReg size.
  2929.     left _ aRectangle origin + (0 @ (aRectangle extent y // 8 + leftNum)).
  2930.     right _ aRectangle origin + (14 * (aRectangle extent x // 15) @ (aRectangle extent y // 8 + rightNum)).
  2931.     name _ 'l' , '#############'.
  2932.     stream _ WriteStream
  2933.                 on: name
  2934.                 from: 2
  2935.                 to: name size.
  2936.     leftShiftReg size printOn: stream.
  2937.     name _ name copyUpTo: $#.
  2938.     newLeftShiftReg _ LeftShiftRegBox
  2939.                 offset: left
  2940.                 withName: name
  2941.                 withForm: LeftShiftRegBox asCursor
  2942.                 superManager: self.
  2943.     leftShiftReg add: newLeftShiftReg.
  2944.     newLeftShiftReg initializePorts.
  2945.     boxes add: newLeftShiftReg.
  2946.     name _ 'r' , '#############'.
  2947.     stream _ WriteStream
  2948.                 on: name
  2949.                 from: 2
  2950.                 to: name size.
  2951.     rightShiftReg size printOn: stream.
  2952.     name _ name copyUpTo: $#.
  2953.     newRightShiftReg _ RightShiftRegBox
  2954.                 offset: right
  2955.                 withName: name
  2956.                 withForm: RightShiftRegBox asCursor
  2957.                 superManager: self.
  2958.     rightShiftReg add: newRightShiftReg.
  2959.     newRightShiftReg initializePorts.
  2960.     boxes add: newRightShiftReg.
  2961.     self addInput: newRightShiftReg.
  2962.     newLeftShiftReg companion: newRightShiftReg.
  2963.     newRightShiftReg companion: newLeftShiftReg.
  2964.     ^newLeftShiftReg boundingBox merge: newRightShiftReg boundingBox! !
  2965.  
  2966.  
  2967. !ControlBoxManager methodsFor: 'calculations'!
  2968.  
  2969. calcLoopControlBoxes
  2970.     "send masterTokens to loop control boxes to update their 
  2971.     values "
  2972.  
  2973.     self subclassResponsibility!
  2974.  
  2975. calculate
  2976.     "execute the subprogram of this ControlBoxManager"
  2977.  
  2978.     inputs isNil ifFalse: [inputs do: [:each | each value isNil ifTrue: [^nil]]].
  2979.     boxes do: [:each | each initValue: nil].
  2980.     self initLoopControlBoxes.
  2981.     super calculate.
  2982.     [self loopTest]
  2983.         whileTrue: 
  2984.             [self calcLoopControlBoxes.
  2985.             super calculate].
  2986.     ^self loopValue!
  2987.  
  2988. initLoopControlBoxes
  2989.     "send tokens to loop control boxes to initialize their values"
  2990.  
  2991.     self subclassResponsibility!
  2992.  
  2993. loopTest
  2994.     "test for the end of execution of the loop"
  2995.  
  2996.     self subclassResponsibility!
  2997.  
  2998. loopValue
  2999.     "return the final value of the loop"
  3000.  
  3001.     self subclassResponsibility! !
  3002.  
  3003.  
  3004. ControlBoxManager subclass: #ForLoopManager
  3005.     instanceVariableNames: 'decrementBox '
  3006.     classVariableNames: ''
  3007.     poolDictionaries: ''
  3008.     category: 'FlowKit'!
  3009. ForLoopManager comment:
  3010. 'ForLoopManager is the concrete class for managers of the subprograms
  3011. of ForLoopBoxes
  3012.  
  3013. The instance variable decrementBox is the ''N'' Box in the
  3014. ForLoopManager''s subprogram
  3015.  
  3016.  
  3017. '!
  3018.  
  3019.  
  3020. !ForLoopManager methodsFor: 'calculations'!
  3021.  
  3022. calcLoopControlBoxes
  3023.     "send masterTokens to loop control boxes to update their   
  3024.     values"
  3025.  
  3026.     rightShiftReg isNil ifFalse: [rightShiftReg do: [:each | each masterToken]].
  3027.     incrementBox masterToken.
  3028.     decrementBox masterToken!
  3029.  
  3030. initLoopControlBoxes
  3031.     "send tokens to loop control boxes to initialize their values"
  3032.  
  3033.     rightShiftReg isNil ifFalse: [rightShiftReg do: [:each | each token]].
  3034.     decrementBox token.
  3035.     incrementBox token!
  3036.  
  3037. loopTest
  3038.     "test for the end of execution of the loop"
  3039.  
  3040.     ^decrementBox firstValue > 0!
  3041.  
  3042. loopValue
  3043.     "return the final value of the loop"
  3044.  
  3045.     ^incrementBox value! !
  3046.  
  3047.  
  3048. !ForLoopManager methodsFor: 'adding'!
  3049.  
  3050. addDecrementBox: aRectangle 
  3051.     "add decrement box"
  3052.     decrementBox _ DecrementBox
  3053.                 offset: aRectangle origin + (aRectangle extent x // 8 @ (aRectangle extent y // 8))
  3054.                 withName: 'N'
  3055.                 withForm: DecrementBox asCursor
  3056.                 superManager: self.
  3057.     decrementBox initializePorts.
  3058.     boxes add: decrementBox.
  3059.      self addInput: decrementBox.! !
  3060.  
  3061.  
  3062. !ForLoopManager methodsFor: 'accessing'!
  3063.  
  3064. isEmpty
  3065.     "Return whether there is anything in this manager 
  3066.     besides the loop control boxes"
  3067.  
  3068.     ^boxes size = (2 + leftShiftReg size + rightShiftReg size)! !
  3069.  
  3070.  
  3071. ControlBoxManager subclass: #WhileLoopManager
  3072.     instanceVariableNames: 'testBox '
  3073.     classVariableNames: ''
  3074.     poolDictionaries: ''
  3075.     category: 'FlowKit'!
  3076. WhileLoopManager comment:
  3077. 'WhileLoopManager is the concrete class for managers of the subprograms
  3078. of WhileLoopBoxes
  3079.  
  3080. The instance variable testBox holds the boolean test Box in the
  3081. WhileLoopManager''s subprogram'!
  3082.  
  3083.  
  3084. !WhileLoopManager methodsFor: 'calculations'!
  3085.  
  3086. calcLoopControlBoxes
  3087.     "send masterTokens to loop control boxes to update their   
  3088.     values"
  3089.  
  3090.     rightShiftReg isNil ifFalse: [rightShiftReg do: [:each | each masterToken]].
  3091.     incrementBox masterToken!
  3092.  
  3093. initLoopControlBoxes
  3094.     "send tokens to loop control boxes to initialize their values"
  3095.  
  3096.     rightShiftReg isNil ifFalse: [rightShiftReg do: [:each | each token]].
  3097.     incrementBox token!
  3098.  
  3099. loopTest
  3100.     "test for the end of execution of the loop"
  3101.  
  3102.     testBox value isNil
  3103.         ifTrue: [^false]
  3104.         ifFalse: [^testBox firstValue]!
  3105.  
  3106. loopValue
  3107.     "return the final value of the loop"
  3108.  
  3109.     ^false! !
  3110.  
  3111.  
  3112. !WhileLoopManager methodsFor: 'adding'!
  3113.  
  3114. addTestBox: aRectangle 
  3115.     "add test box"
  3116.  
  3117.     testBox _ TestBox
  3118.                 offset: aRectangle origin + (3 * (aRectangle extent x // 4) @ (3 * (aRectangle extent y // 4)))
  3119.                 withName: '?'
  3120.                 withForm:  TestBox asCursor
  3121.                 superManager: self.
  3122.     testBox initializePorts.
  3123.     boxes add: testBox! !
  3124.  
  3125.  
  3126. !WhileLoopManager methodsFor: 'accessing'!
  3127.  
  3128. isEmpty
  3129. "Return whether there is anything in this FoibleManager 
  3130.     besides the loop control boxes"
  3131.  
  3132.     ^boxes size = (2 + leftShiftReg size + rightShiftReg size)! !
  3133.  
  3134.  
  3135. Object subclass: #FlowKitDirectory
  3136.     instanceVariableNames: ''
  3137.     classVariableNames: ''
  3138.     poolDictionaries: ''
  3139.     category: 'FlowKit'!
  3140.  
  3141. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  3142.  
  3143. FlowKitDirectory class
  3144.     instanceVariableNames: ''!
  3145.  
  3146.  
  3147. !FlowKitDirectory class methodsFor: 'form access'!
  3148.  
  3149. iconDirectory
  3150.     "return the directory that contains the icons for the FlowKit"
  3151.  
  3152.     ^'/jindrich/icons'! !
  3153.  
  3154.  
  3155. InputPort subclass: #FlowKitInputPort
  3156.     instanceVariableNames: 'value '
  3157.     classVariableNames: ''
  3158.     poolDictionaries: ''
  3159.     category: 'FlowKit'!
  3160. FlowKitInputPort comment:
  3161. 'FlowKitInputPort is the concrete class for Input Ports
  3162.  
  3163. The instance variable value holds the value of the FlowKitInputPort'!
  3164.  
  3165.  
  3166. !FlowKitInputPort methodsFor: 'accessing'!
  3167.  
  3168. value
  3169.     "return the value of the receiver"
  3170.  
  3171.     ^value! !
  3172.  
  3173.  
  3174. !FlowKitInputPort methodsFor: 'calculations'!
  3175.  
  3176. token: aValue
  3177.     "the sender has a new value for use in the    receiver's box's calculation"
  3178.  
  3179.      value _ aValue.
  3180.      box token! !
  3181.  
  3182.  
  3183. OutputPort subclass: #FlowKitOutputPort
  3184.     instanceVariableNames: ''
  3185.     classVariableNames: ''
  3186.     poolDictionaries: ''
  3187.     category: 'FlowKit'!
  3188. FlowKitOutputPort comment:
  3189. 'FlowKitOutputPort is the concrete class for Output Ports'!
  3190.  
  3191.  
  3192. !FlowKitOutputPort methodsFor: 'calculations'!
  3193.  
  3194. token: aValue 
  3195.     "the receiver has a new value, pass the value to its link"
  3196.  
  3197.     link isNil 
  3198.             ifFalse: [(1 to: link size)
  3199.                         do: [:i | (link at: i) token: aValue]]
  3200.  
  3201. "ifFalse: [link token: aValue]"! !
  3202.  
  3203.  
  3204. Tool subclass: #FlowKitTool
  3205.     instanceVariableNames: ''
  3206.     classVariableNames: ''
  3207.     poolDictionaries: ''
  3208.     category: 'FlowKit'!
  3209. FlowKitTool comment:
  3210. 'FlowKitTool is the abstract class for all Tools in FlowKit'!
  3211.  
  3212.  
  3213. !FlowKitTool methodsFor: 'menu messages'!
  3214.  
  3215. add: aClass 
  3216.     "Get a point in the viewport and add a Foible of the class     
  3217.           aClass there"
  3218.  
  3219.     | aPoint aThing aBox currentModel aCursor |
  3220.     currentModel _ model.
  3221.     aCursor _ aClass asCursor.
  3222.     aPoint _ self getThingPoint: aCursor.
  3223.     aPoint isNil ifTrue: [^nil].
  3224.     currentModel _ self getManager: aPoint.
  3225.     currentModel isNil ifTrue: [^nil].
  3226.     aThing _ currentModel addBox: [:name | aClass
  3227.                     offset: aPoint
  3228.                     withName: name
  3229.                     withForm: aCursor
  3230.                     superManager: currentModel]. 
  3231.     model changed: aThing!
  3232.  
  3233. add: aClass withForm: aForm 
  3234.     "Get a point in the viewport and add a Foible of the class     
  3235.            aClass there. Then reset the permanent form"
  3236.  
  3237.     | aPoint aThing aBox currentModel aCursor |
  3238.     currentModel _ model.
  3239.     aCursor _ aForm.
  3240.     aPoint _ self getThingPoint: aCursor.
  3241.     aPoint isNil ifTrue: [^nil].
  3242.     currentModel _ self getManager: aPoint.
  3243.     currentModel isNil ifTrue: [^nil].
  3244.     aThing _ currentModel addBox: [:name | aClass
  3245.                     offset: aPoint
  3246.                     withName: name
  3247.                     withForm: aCursor]. 
  3248.     currentModel lastBox permanentForm: aClass asCursor.
  3249.     model changed: aThing!
  3250.  
  3251. addWithCompanion: aClass 
  3252.     "add a Box of class aClass and a companion Box for it in the 
  3253.      other view"
  3254.  
  3255.     | otherModel otherView aPoint aBox aRectangle boxManager |
  3256.     otherView _ self otherView.
  3257.     otherModel _ otherView model.
  3258.     aPoint _ otherView boundingBox center.
  3259.     aBox _ otherModel find: aPoint.
  3260.     aBox isNil ifFalse: [boxManager _ aBox manager].
  3261.     boxManager isNil ifTrue: [boxManager _ otherModel].
  3262.     self add: aClass.
  3263.     aRectangle _ boxManager add: aClass companionClass at: aPoint.
  3264.     otherModel changed: aRectangle.
  3265.     boxManager lastBox companion: model lastBox.
  3266.     model lastBox companion: boxManager lastBox!
  3267.  
  3268. getManager: aPoint 
  3269.     "return the manager of the box at aPoint"
  3270.  
  3271.     | aBox |
  3272.     aBox _ model find: aPoint.
  3273.     aBox isNil
  3274.         ifTrue: [^model]
  3275.         ifFalse: [^aBox manager]! !
  3276.  
  3277.  
  3278. !FlowKitTool methodsFor: 'subview access'!
  3279.  
  3280. otherView
  3281.     "it returns the other subview of the receiver's view's 
  3282.     superview "
  3283.  
  3284.     ^view superView otherView: view! !
  3285.  
  3286. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  3287.  
  3288. FlowKitTool class
  3289.     instanceVariableNames: ''!
  3290.  
  3291.  
  3292. !FlowKitTool class methodsFor: 'form access'!
  3293.  
  3294. iconDirectory
  3295.     "return the directory that contains the icons for FlowKit"
  3296.  
  3297.     ^FlowKitDirectory iconDirectory! !
  3298.  
  3299.  
  3300. FlowKitTool subclass: #BooleanTool
  3301.     instanceVariableNames: ''
  3302.     classVariableNames: ''
  3303.     poolDictionaries: ''
  3304.     category: 'FlowKit'!
  3305. BooleanTool comment:
  3306. 'BooleanTool is the concrete class for Tools that add Boxes that inherit from BooleanBox'!
  3307.  
  3308.  
  3309. !BooleanTool methodsFor: 'menu messages'!
  3310.  
  3311. andBox
  3312.     self add: AndBox!
  3313.  
  3314. notBox
  3315.     self add: NotBox!
  3316.  
  3317. orBox
  3318.     self add: OrBox! !
  3319.  
  3320.  
  3321. !BooleanTool methodsFor: 'menu setup'!
  3322.  
  3323. installMenu
  3324.     "Install our menu"
  3325.  
  3326.     controller yellowButtonMenu: (PopUpMenu labels: 'invert
  3327. and
  3328. or')
  3329.         yellowButtonMessages: #(notBox andBox orBox)! !
  3330.  
  3331.  
  3332. FlowKitTool subclass: #ComparisonTool
  3333.     instanceVariableNames: ''
  3334.     classVariableNames: ''
  3335.     poolDictionaries: ''
  3336.     category: 'FlowKit'!
  3337. ComparisonTool comment:
  3338. 'ComparisonTool is the concrete class for Tools that add Boxes that inherit from ComparisonBox'!
  3339.  
  3340.  
  3341. !ComparisonTool methodsFor: 'menu setup'!
  3342.  
  3343. installMenu
  3344.     "Install our menu"
  3345.  
  3346.     controller yellowButtonMenu: (PopUpMenu labels: 'numeric comparison 
  3347. zero comparison')
  3348.         yellowButtonMessages: #(numericComparisonBox zeroComparisonBox)! !
  3349.  
  3350.  
  3351. !ComparisonTool methodsFor: 'menu messages'!
  3352.  
  3353. numericComparisonBox
  3354.  
  3355. self add: NumericComparisonBox!
  3356.  
  3357. zeroComparisonBox
  3358.  
  3359. self add: ZeroComparisonBox! !
  3360.  
  3361. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  3362.  
  3363. ComparisonTool class
  3364.     instanceVariableNames: ''!
  3365.  
  3366.  
  3367. !ComparisonTool class methodsFor: 'accessing'!
  3368.  
  3369. cursorOffset
  3370.     "Return the offset of my cursor"
  3371.  
  3372.     ^-8 @ -9! !
  3373.  
  3374.  
  3375. FlowKitTool subclass: #ControlTool
  3376.     instanceVariableNames: ''
  3377.     classVariableNames: ''
  3378.     poolDictionaries: ''
  3379.     category: 'FlowKit'!
  3380. ControlTool comment:
  3381. 'ControlTool is the concrete class for Tools that add Boxes that inherit from ControlBox'!
  3382.  
  3383.  
  3384. !ControlTool methodsFor: 'menu setup'!
  3385.  
  3386. installMenu
  3387.     "Install our menu"
  3388.  
  3389.     controller yellowButtonMenu: (PopUpMenu labels: 'while loop 
  3390. for loop
  3391. shift register')
  3392.         yellowButtonMessages: #(whileLoop forLoop addShiftReg )! !
  3393.  
  3394.  
  3395. !ControlTool methodsFor: 'menu messages'!
  3396.  
  3397. addShiftReg
  3398.     "Get a ControlBox and add a pair of shift registers there"
  3399.  
  3400.     | aBox aPoint currentModel aThing |
  3401.     aPoint _ self getPoint: PlacementTool arrowsCursor.
  3402.     aPoint isNil ifTrue: [^nil].
  3403.     "User aborted"
  3404.     aBox _ model find: aPoint suchThat: [:it | it canMoveIndependently].
  3405.     aBox isNil ifTrue: [^nil].
  3406.     currentModel _ aBox manager.
  3407.     currentModel isNil ifTrue: [^nil].
  3408.     aThing _ currentModel addShiftRegTo: aBox boundingBox.
  3409.     aThing isNil ifTrue: [^nil].
  3410.     model changed: aThing!
  3411.  
  3412. forLoop
  3413.     "add a new forLoop"
  3414.  
  3415.      self add: ForLoopBox!
  3416.  
  3417. whileLoop
  3418.     "add a new whileLoop"
  3419.  
  3420.      self add: WhileLoopBox! !
  3421.  
  3422.  
  3423. FlowKitTool subclass: #FunctionTool
  3424.     instanceVariableNames: ''
  3425.     classVariableNames: ''
  3426.     poolDictionaries: ''
  3427.     category: 'FlowKit'!
  3428. FunctionTool comment:
  3429. 'FunctionTool is the concrete class for Tools that add Boxes that inherit from FunctionBox'!
  3430.  
  3431.  
  3432. !FunctionTool methodsFor: 'menu setup'!
  3433.  
  3434. installMenu
  3435.     "Install our menu"
  3436.  
  3437.     controller yellowButtonMenu: (PopUpMenu labels: 'addition 
  3438. multiplication
  3439. subtraction
  3440. integer division
  3441. real division
  3442. minimum
  3443. maximum')
  3444.         yellowButtonMessages: #(additionBox multiplicationBox subtractionBox integerDivisionBox realDivisionBox minBox maxBox)! !
  3445.  
  3446.  
  3447. !FunctionTool methodsFor: 'menu messages'!
  3448.  
  3449. additionBox
  3450.     self add: AdditionBox!
  3451.  
  3452. integerDivisionBox
  3453.     self add: IntegerDivisionBox!
  3454.  
  3455. maxBox
  3456.     self add: MaxBox!
  3457.  
  3458. minBox
  3459.     self add: MinBox!
  3460.  
  3461. multiplicationBox
  3462.     self add: MultiplicationBox!
  3463.  
  3464. realDivisionBox
  3465.     self add: RealDivisionBox!
  3466.  
  3467. subtractionBox
  3468.     self add: SubtractionBox! !
  3469.  
  3470. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  3471.  
  3472. FunctionTool class
  3473.     instanceVariableNames: ''!
  3474.  
  3475.  
  3476. !FunctionTool class methodsFor: 'accessing'!
  3477.  
  3478. cursorOffset
  3479.     " return the offset of my cursor "
  3480.  
  3481.     ^ -8 @ -9! !
  3482.  
  3483.  
  3484. FlowKitTool subclass: #InputTool
  3485.     instanceVariableNames: ''
  3486.     classVariableNames: ''
  3487.     poolDictionaries: ''
  3488.     category: 'FlowKit'!
  3489. InputTool comment:
  3490. 'InputTool is the concrete class for Tools that add Boxes that inherit from InputBox'!
  3491.  
  3492.  
  3493. !InputTool methodsFor: 'menu setup'!
  3494.  
  3495. installMenu
  3496.     "Install our menu"
  3497.  
  3498.     controller yellowButtonMenu: (PopUpMenu labels: 'Numeric-Box
  3499. Numeric-Random
  3500. Numeric-Tuner
  3501. Numeric-Slider
  3502. Boolean-Light
  3503. Boolean-Hand
  3504. Boolean-Arrows' lines: #(4 ) )
  3505.         yellowButtonMessages: #(numericInputBox randomNumberInputBox
  3506. digitalTunerInputBox sliderInputBox booleanLightInput booleanHandInput 
  3507. booleanArrowsInput)! !
  3508.  
  3509.  
  3510. !InputTool methodsFor: 'menu messages'!
  3511.  
  3512. booleanArrowsInput
  3513.     self addWithCompanion: BooleanArrowsInput!
  3514.  
  3515. booleanHandInput
  3516.     self addWithCompanion: BooleanHandInput!
  3517.  
  3518. booleanLightInput
  3519.     self addWithCompanion: BooleanLightInput!
  3520.  
  3521. digitalTunerInputBox
  3522.     self addWithCompanion: DigitalTunerInputBox!
  3523.  
  3524. numericInputBox
  3525.     self addWithCompanion: NumericInputBox!
  3526.  
  3527. randomNumberInputBox
  3528.     self addWithCompanion: RandomNumberInputBox!
  3529.  
  3530. sliderInputBox
  3531.     self addWithCompanion: SliderInputBox! !
  3532.  
  3533. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  3534.  
  3535. InputTool class
  3536.     instanceVariableNames: ''!
  3537.  
  3538.  
  3539. !InputTool class methodsFor: 'accessing'!
  3540.  
  3541. cursorOffset
  3542.     " return the offset of my cursor "
  3543.  
  3544.     ^-16 @ -16! !
  3545.  
  3546.  
  3547. FlowKitTool subclass: #LabelTool
  3548.     instanceVariableNames: ''
  3549.     classVariableNames: ''
  3550.     poolDictionaries: ''
  3551.     category: 'FlowKit'!
  3552. LabelTool comment:
  3553. 'LabelTool is the concrete class for Tools that add LabelBoxes'!
  3554.  
  3555.  
  3556. !LabelTool methodsFor: 'menu setup'!
  3557.  
  3558. installMenu
  3559.     "Install our menu"
  3560.  
  3561.     controller yellowButtonMenu: (PopUpMenu labels: 'new label')
  3562.         yellowButtonMessages: #(newLabel)! !
  3563.  
  3564.  
  3565. !LabelTool methodsFor: 'menu messages'!
  3566.  
  3567. newLabel
  3568.     "add a foible of type LabelBox"
  3569.  
  3570.     self add: LabelBox! !
  3571.  
  3572.  
  3573. FlowKitTool subclass: #OperatingTool
  3574.     instanceVariableNames: 'started '
  3575.     classVariableNames: 'CurrentCursor '
  3576.     poolDictionaries: ''
  3577.     category: 'FlowKit'!
  3578. OperatingTool comment:
  3579. 'OperatingTool is the concrete class for Tools that allow the user to enter input into Boxes
  3580. '!
  3581.  
  3582.  
  3583. !OperatingTool methodsFor: 'initialize'!
  3584.  
  3585. startUp
  3586.     started _ false.
  3587.     super startUp! !
  3588.  
  3589.  
  3590. !OperatingTool methodsFor: 'menu messages'!
  3591.  
  3592. autoStartOff
  3593.     "take program out of auto-start mode"
  3594.  
  3595.     self started: false.
  3596.     self installMenu!
  3597.  
  3598. autoStartOn
  3599.     "initialize self and put program in auto start mode"
  3600.     
  3601.     self started: true.
  3602.     self installMenu!
  3603.  
  3604. calculate
  3605.     "start calculation of all of the foibles"
  3606.  
  3607.     | aRectangle otherView otherModel |
  3608.     self started
  3609.         ifTrue: 
  3610.             [otherView _ self otherView.
  3611.             otherModel _ otherView model.
  3612.             otherModel calculate.
  3613.             aRectangle _ model displayBox.
  3614.             aRectangle isNil ifFalse: [model changed: #value with: aRectangle]]!
  3615.  
  3616. calibrate
  3617.     "Find a box, if it can be calibrated, ask it to do so"
  3618.  
  3619.     | aThing newPoint currentModel |
  3620.     newPoint _ self getPoint: self class calibrateCursor.
  3621.     currentModel _ model.
  3622.     newPoint isNil ifTrue: [^nil].
  3623.     "User aborted"
  3624.     aThing _ model find: newPoint suchThat: [:it | it canBeCalibrated].
  3625.     aThing isNil ifTrue: [^false].
  3626.     aThing calibrate!
  3627.  
  3628. change
  3629.     "give new input to the given FoibleBox"
  3630.  
  3631.     | aThing aPoint aRectangle newModel thingName newInput |
  3632.     aPoint _ self getPoint: Cursor currentCursor.
  3633.     aPoint isNil ifTrue: [^nil].
  3634.     aThing _ model find: aPoint.
  3635.     aThing isNil ifTrue: [^nil].
  3636.     newModel _ aThing owner. 
  3637.     thingName _ aThing name.
  3638.     aThing canAcceptInput
  3639.         ifTrue: 
  3640.             [newInput _ aThing acceptInput: aPoint - aThing offset.
  3641.             aRectangle _ newModel changeValue: thingName to: newInput.
  3642.             aRectangle class == String
  3643.                 ifTrue: [PopUpNotifier message: aRectangle]
  3644.                 ifFalse: 
  3645.                     [model changed: #value with: aRectangle.
  3646.                     self calculate]]!
  3647.  
  3648. redButtonActivity
  3649.     "red button activity for OperatingTool"
  3650.  
  3651.     self change!
  3652.  
  3653. start
  3654.     "initialize self and put program in started state"
  3655.     
  3656.     self started: true.
  3657.     self calculate.
  3658.     self started: false! !
  3659.  
  3660.  
  3661. !OperatingTool methodsFor: 'menu setup'!
  3662.  
  3663. buildYellowButtonMenu
  3664.     "answer with the yellow button menu for operating tool"
  3665.  
  3666.     self started
  3667.         ifTrue: [^'Calibrate
  3668. Auto-Start Off
  3669. Open Layout
  3670. Save Layout']
  3671.         ifFalse: [^'Calibrate
  3672. Start (Manual)
  3673. Auto-Start On
  3674. Open Layout
  3675. Save Layout']!
  3676.  
  3677. buildYellowButtonMessages
  3678.     "answer messages for yellowbutton"
  3679.  
  3680.     self started
  3681.         ifTrue: [^#(calibrate autoStartOff open save )]
  3682.         ifFalse: [^#(calibrate start autoStartOn open save )]!
  3683.  
  3684. installMenu
  3685.     "Install our menu"
  3686.  
  3687.     controller yellowButtonMenu:
  3688.                  (PopUpMenu labels: self buildYellowButtonMenu 
  3689.                                  lines: (self yellowButtonMenuLines))
  3690.                 yellowButtonMessages: self buildYellowButtonMessages!
  3691.  
  3692. yellowButtonMenuLines
  3693.     "answer with array of lines used on yellow button menu for operating tool"
  3694.  
  3695.     self started
  3696.         ifTrue: [^#(1 2)]
  3697.         ifFalse: [^#(1 3)]! !
  3698.  
  3699.  
  3700. !OperatingTool methodsFor: 'private'!
  3701.  
  3702. getPoint: aCursor
  3703.  
  3704.     "Get a point in the viewport and return its value, nil if left the viewport"
  3705.  
  3706.     | aPoint |
  3707.     aCursor show.
  3708.     [ Sensor noButtonPressed & controller isControlActive ]
  3709.             whileTrue: [aPoint _ Sensor cursorPoint].
  3710.  
  3711.     model cursor show.
  3712.     controller isControlActive ifFalse: [^nil].
  3713.     ^(view inverseDisplayTransform: (Sensor waitButton)) rounded! !
  3714.  
  3715.  
  3716. !OperatingTool methodsFor: 'accessing'!
  3717.  
  3718. started
  3719.     "answer started or not"
  3720.  
  3721.     ^started!
  3722.  
  3723. started: aBoolean
  3724.     "turn on/off"
  3725.  
  3726.     started _ aBoolean! !
  3727.  
  3728. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  3729.  
  3730. OperatingTool class
  3731.     instanceVariableNames: 'calibrateCursor '!
  3732.  
  3733.  
  3734. !OperatingTool class methodsFor: 'accessing'!
  3735.  
  3736. calibrateCursor
  3737.  
  3738.     calibrateCursor notNil
  3739.         ifTrue: [^calibrateCursor].
  3740.     ^calibrateCursor _ (self getCursor: 'Calibrate.cur') offset: -7@-7!
  3741.  
  3742. cursorOffset
  3743.     "Return the offset of my cursor"
  3744.  
  3745.     ^ 0 @ -6! !
  3746.  
  3747.  
  3748. FlowKitTool subclass: #OutputTool
  3749.     instanceVariableNames: ''
  3750.     classVariableNames: ''
  3751.     poolDictionaries: ''
  3752.     category: 'FlowKit'!
  3753. OutputTool comment:
  3754. 'OutputTool is the concrete class for Tools that add Boxes that inherit from OutputBox'!
  3755.  
  3756.  
  3757. !OutputTool methodsFor: 'menu setup'!
  3758.  
  3759. installMenu
  3760.     "Install our menu"
  3761.  
  3762.     controller yellowButtonMenu: (PopUpMenu labels: 'Numeric-Box
  3763. Numeric-LED Meter
  3764. Numeric-Analog Meter
  3765. Numeric-Plotter
  3766. Boolean-Light
  3767. Boolean-Hand
  3768. Boolean-Arrows' lines: #(4 ))
  3769.         yellowButtonMessages: #(numericOutputBox ledMeterOutputBox analogMeterOutputBox plottedOutputBox booleanLight booleanHand booleanArrows )! !
  3770.  
  3771.  
  3772. !OutputTool methodsFor: 'menu messages'!
  3773.  
  3774. analogMeterOutputBox
  3775.     
  3776.     self addWithCompanion: AnalogMeterOutputBox!
  3777.  
  3778. booleanArrows
  3779.     self addWithCompanion: BooleanArrows!
  3780.  
  3781. booleanHand
  3782.     self addWithCompanion: BooleanHand!
  3783.  
  3784. booleanLight
  3785.     self addWithCompanion: BooleanLight!
  3786.  
  3787. ledMeterOutputBox
  3788.     self addWithCompanion: LEDMeterOutputBox!
  3789.  
  3790. numericOutputBox
  3791.     self addWithCompanion: NumericOutputBox!
  3792.  
  3793. plottedOutputBox
  3794.     self addWithCompanion: PlottedOutputBox! !
  3795.  
  3796. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  3797.  
  3798. OutputTool class
  3799.     instanceVariableNames: ''!
  3800.  
  3801.  
  3802. !OutputTool class methodsFor: 'accessing'!
  3803.  
  3804. cursorOffset
  3805.     "Return the offset of my cursor"
  3806.  
  3807.     ^-16 @ -16! !
  3808.  
  3809.  
  3810. FlowKitTool subclass: #PlacementTool
  3811.     instanceVariableNames: ''
  3812.     classVariableNames: ''
  3813.     poolDictionaries: ''
  3814.     category: 'FlowKit'!
  3815. PlacementTool comment:
  3816. 'PlacementTool is the concrete class for Tools that allow the user to move, copy, and delete Boxes'!
  3817.  
  3818.  
  3819. !PlacementTool methodsFor: 'menu messages'!
  3820.  
  3821. copy
  3822.     "Find an object and copy it"
  3823.  
  3824.     | oldThing newPoint newImage aBox currentModel |
  3825.     newPoint _ self getPoint: self class arrowsCursor.
  3826.     currentModel _ model.
  3827.     newPoint isNil ifTrue: [^nil].
  3828.     "User aborted"
  3829.     oldThing _ model find: newPoint suchThat: [:it | it canBeCopied].
  3830.     oldThing isNil ifTrue: [^false].
  3831.     Sensor cursorPoint: (view displayTransform: oldThing offset).
  3832.     newImage _ oldThing class asCursor.
  3833.     newPoint _ self getThingPoint: newImage.
  3834.     newPoint isNil ifTrue: [^nil].
  3835.     currentModel _ self getManager: newPoint.
  3836.     currentModel isNil ifTrue: [^nil].
  3837.     "The thing already exists, abort"
  3838.     Cursor wait show.
  3839.     oldThing _ currentModel addBox: [:name | oldThing class
  3840.                     offset: newPoint
  3841.                     withName: name
  3842.                     withForm: newImage].
  3843.     model changed: oldThing.
  3844.     model cursor show.!
  3845.  
  3846. delete
  3847.     "Find an object and remove it from list, return nil if no find"
  3848.  
  3849.     | aPoint aThing aRectangle otherView otherModel companionBox otherRectangle |
  3850.     aPoint _ self getPoint: self class skullCursor.
  3851.     aPoint isNil ifTrue: [^nil].
  3852.     "User aborted"
  3853.     aThing _ model find: aPoint suchThat: [:it | it canBeDeleted].
  3854.     aThing isNil ifTrue: [^nil].
  3855.     "No such object"
  3856.     (BinaryChoice message: 'Really delete
  3857. ' , aThing name , '?')
  3858.         ifFalse: [^nil].
  3859.     aRectangle _ aThing owner remove: aThing.
  3860.     model changed: aRectangle.
  3861.     otherView _ self otherView.
  3862.     otherModel _ otherView model.
  3863.     companionBox _ aThing companion.
  3864.     companionBox isNil
  3865.         ifFalse: 
  3866.             [otherRectangle _companionBox owner remove: companionBox.
  3867.             otherModel changed: otherRectangle]!
  3868.  
  3869. move
  3870.     "Find an object and move it"
  3871.  
  3872.     | oldThing newPoint aRectangle currentModel aBox |
  3873.     newPoint _ self getPoint: self class cursor.
  3874.     newPoint isNil ifTrue: [^nil].    "User aborted"
  3875.  
  3876.     oldThing _ model find: newPoint suchThat: [:it | it canMoveIndependently].
  3877.     oldThing isNil ifTrue: [^nil].
  3878.     (oldThing isKindOf: self defaultLinkClass)
  3879.         ifTrue: [aRectangle_self moveLine: oldThing 
  3880.                                     point: newPoint].
  3881.     (oldThing isKindOf: FoibleBox)
  3882.         ifTrue: [oldThing companion isNil 
  3883.                     ifFalse: [Display flash: (self otherView displayTransform: oldThing companion boundingBox)].
  3884.                     Sensor cursorPoint: (view displayTransform: oldThing offset).
  3885.                     newPoint _ self getThingPoint: oldThing ghostForm.
  3886.                     newPoint isNil ifTrue: [^nil].
  3887.                     currentModel _ model.
  3888.                     aBox _ model find: newPoint suchThat: [:it | it isKindOf: FoibleBox].
  3889.                     aBox notNil
  3890.                         ifTrue: [aBox = oldThing
  3891.                             ifTrue: [currentModel _ aBox owner]
  3892.                             ifFalse: [aBox manager notNil
  3893.                                 ifTrue: [currentModel _ aBox manager]
  3894.                                 ifFalse: [currentModel _ aBox owner]].
  3895.                             oldThing manager notNil
  3896.                                 ifTrue: [(aBox inside: oldThing manager)
  3897.                                     ifTrue: [currentModel _ oldThing owner]]  ].
  3898.                     Cursor wait show. 
  3899.                     aRectangle _ currentModel
  3900.                                         moveBox: oldThing
  3901.                                         byBlock: [:box | box offset: newPoint]].
  3902.     aRectangle notNil
  3903.         ifTrue: [model changed: aRectangle].
  3904.     model cursor show!
  3905.  
  3906. redButtonActivity
  3907.     self move! !
  3908.  
  3909.  
  3910. !PlacementTool methodsFor: 'menu setup'!
  3911.  
  3912. installMenu
  3913.     "Install our menu"
  3914.  
  3915.     controller yellowButtonMenu: (PopUpMenu labels: 'delete
  3916.  copy')
  3917.         yellowButtonMessages: #(delete copy )! !
  3918.  
  3919. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  3920.  
  3921. PlacementTool class
  3922.     instanceVariableNames: 'arrowsCursor skullCursor '!
  3923.  
  3924.  
  3925. !PlacementTool class methodsFor: 'accessing'!
  3926.  
  3927. arrowsCursor
  3928.  
  3929.     arrowsCursor isNil ifTrue: [arrowsCursor _ (self getCursor: 'Arrows.cur') offset: -7@-7].
  3930.     ^arrowsCursor!
  3931.  
  3932. cursorOffset
  3933.     "Return the offset of my cursor"
  3934.  
  3935.     ^ -8 @ -9!
  3936.  
  3937. skullCursor
  3938.  
  3939.     skullCursor isNil ifTrue: [skullCursor _ (self getCursor: 'Skull.cur') offset: -7@-9].
  3940.     ^skullCursor! !
  3941.  
  3942.  
  3943. !PlacementTool class methodsFor: 'class initialization'!
  3944.  
  3945. initializeForms
  3946.     " send this class method when the form for my icon or cursor has been changed "
  3947.     " <class name> initializeForms  "
  3948.  
  3949.     icon _ self getIcon.
  3950.     skullCursor _ (self getCursor: 'Skull.cur') offset: -7@-9.
  3951.     arrowsCursor _ (self getCursor: 'Arrows.cur') offset: -7@-7.
  3952.     toolCursor _ self getCursor offset: self cursorOffset.! !
  3953.  
  3954.  
  3955. FlowKitTool subclass: #WiringTool
  3956.     instanceVariableNames: ''
  3957.     classVariableNames: ''
  3958.     poolDictionaries: ''
  3959.     category: 'FlowKit'!
  3960. WiringTool comment:
  3961. 'WiringTool is the concrete class for Tools that add Links '!
  3962.  
  3963.  
  3964. !WiringTool methodsFor: 'menu setup'!
  3965.  
  3966. installMenu "install our menu"
  3967.  
  3968.     controller yellowButtonMenu: nil
  3969.         yellowButtonMessages: nil! !
  3970.  
  3971.  
  3972. !WiringTool methodsFor: 'menu messages'!
  3973.  
  3974. add 
  3975. "link this type of link"
  3976.  
  3977.     | fromThing toThing link path aProtoLink lines |
  3978.     aProtoLink _ self getPath.
  3979.     aProtoLink isNil ifTrue: [^nil].
  3980.     fromThing _ aProtoLink origin.
  3981.     toThing _ aProtoLink destination.
  3982.     lines _ aProtoLink lines.
  3983.     link _fromThing box owner 
  3984.                 addLink: WiringLink
  3985.                 from: fromThing
  3986.                 to: toThing
  3987.                 withPath: lines.
  3988.     link isNil ifTrue: [^nil].
  3989.     model changed: link.!
  3990.  
  3991. redButtonActivity
  3992.     "red button activity for WiringLinkTool"
  3993.  
  3994.     self add! !
  3995.  
  3996. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  3997.  
  3998. WiringTool class
  3999.     instanceVariableNames: ''!
  4000.  
  4001.  
  4002. !WiringTool class methodsFor: 'accessing'!
  4003.  
  4004. cursorOffset
  4005.     "Return the offset of my cursor"
  4006.  
  4007.     ^-12 @ -1! !
  4008.  
  4009.  
  4010. ToolBenchView subclass: #FlowKitView
  4011.     instanceVariableNames: ''
  4012.     classVariableNames: ''
  4013.     poolDictionaries: ''
  4014.     category: 'FlowKit'!
  4015.  
  4016.  
  4017. !FlowKitView methodsFor: 'subview access'!
  4018.  
  4019. canvas
  4020.     ^canvas!
  4021.  
  4022. otherView: aView 
  4023.     " return a subview in canvas that is not equal to aView"
  4024.  
  4025.     self canvas do: [:each | each ~= aView ifTrue: [^each]].
  4026.     ^nil! !
  4027.  
  4028.  
  4029. !FlowKitView methodsFor: 'initialize'!
  4030.  
  4031. initializeWithModel: aFoibleProgram
  4032.     "Add the two sub-views: 2 canvases (with a dummy form for now)"
  4033.  
  4034.     | frontView backView |
  4035.     self model: aFoibleProgram.
  4036.     frontView _ CanvasView new.
  4037.     frontView model: (aFoibleProgram firstManager).
  4038.     self addSubView: frontView in: (0@0 extent: 0.5@1) borderWidth: 1.
  4039.     backView _ CanvasView new.
  4040.     backView model: (aFoibleProgram secondManager).
  4041.     self addSubView: backView in: (0.5@0 extent: 0.5@1) borderWidth: 1.
  4042.     canvas _ OrderedCollection with: frontView with: backView! !
  4043.  
  4044.  
  4045. !FlowKitView methodsFor: 'private'!
  4046.  
  4047. installCanvasTools
  4048.     "tell my canvases what their Tools are"
  4049.  
  4050.     (self canvas at: 1) addTools: (OrderedCollection new
  4051.         add: OperatingTool new;
  4052.         add: PlacementTool new;
  4053.         add: LabelTool new;
  4054.         add: NullTool new;
  4055.         add: NullTool new;
  4056.         add: NullTool new;
  4057.         add: NullTool new;
  4058.         add: InputTool new;
  4059.         add: OutputTool new;
  4060.         add: NullTool new;
  4061.         yourself).    
  4062.     (self canvas at: 2) addTools: (OrderedCollection new
  4063.         add: OperatingTool new;
  4064.         add: PlacementTool new;
  4065.         add: LabelTool new;
  4066.         add: WiringTool new;
  4067.         add: FunctionTool new;
  4068.         add: ComparisonTool new;
  4069.         add: BooleanTool new;
  4070.         add: NullTool new;
  4071.         add: NullTool new;
  4072.         add: ControlTool new;
  4073.         yourself)!
  4074.  
  4075. tools
  4076.     "return an OrderdCollection of the icons for the palette"
  4077.  
  4078.     ^(OrderedCollection new
  4079.         add: OperatingTool icon;
  4080.         add: PlacementTool icon;
  4081.         add: LabelTool icon;
  4082.         add: WiringTool icon;
  4083.         add: FunctionTool icon;
  4084.         add: ComparisonTool icon;
  4085.         add: BooleanTool icon;
  4086.         add: InputTool icon;
  4087.         add: OutputTool icon;
  4088.         add: ControlTool icon;
  4089.         yourself)! !
  4090.  
  4091. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  4092.  
  4093. FlowKitView class
  4094.     instanceVariableNames: ''!
  4095.  
  4096.  
  4097. !FlowKitView class methodsFor: 'instance creation'!
  4098.  
  4099. open
  4100.     "Create a new FlowKitManager and open a FlowKitView on it"
  4101.     "FlowKitView open."
  4102.  
  4103.     self openOn: (FoibleProgram with: FlowKitManager new with: FlowKitManager new)!
  4104.  
  4105. openProgram
  4106.     "Open an existing FlowKitView program; saved as a binary"
  4107.     "FlowKitView openProgram." 
  4108.  
  4109.     ^super openProgram!
  4110.  
  4111. openProgram: aName 
  4112.     "Open an existing FlowKitView program saved as a binary"
  4113.     "FlowKitView openProgram: <aName>. "
  4114.  
  4115.     ^super openProgram: aName! !
  4116.  
  4117.